题目链接:点击查看

题目大意:给出n只狐狸,需要按照下列要求为其安排座位:

  1. 每只狐狸必须都要有位置
  2. 每张圆桌至少坐三只狐狸
  3. 相邻每两只狐狸的年龄和必须是素数

要求判断能否在符合上述要求的情况下分配座位

题目分析:首先考虑到素数,肯定不能是两个奇数或两个偶数相邻,因为两个奇数或两个偶数相邻的和必是偶数,而每一只狐狸的年龄都是大于等于2的,此时组合出来的偶数必定不是素数,所以我们可以选择奇偶建边,目的是为了让每个奇数都能与两个偶数匹配,同时每个偶数都能与两个奇数匹配,如果可以完全匹配那么肯定可以组成环,那么就可以这样建边了:

  1. 源点->所有奇数,流量为2
  2. 所有奇数->可以组成素数的偶数,流量为1
  3. 所有偶数->汇点,流量为2

这样建完边后跑一遍最大流,若流量等于n的话才说明有解,否则直接输出impossible就行了

剩下的就是怎么找到所有的解了,因为我们对于奇数与偶数之间建边时,流量为1,若在最大流的过程中遍历到了某条边,那么这条边的流量将被改变成了0,我们只需要找到所有边权为0的点将两个端点建边,等我们又建好一张图后,直接用dfs跑答案就好了,每次跑到一个环就输出

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=210;int a[N];vector<int>node[N],ans;bool vis[N];struct Edge
{int to,w,next;
}edge[N*N];//边数int head[N],cnt;void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N*N];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}bool is_pri(int x)
{if(x<2)return false;for(int i=2;i*i<=x;i++)if(x%i==0)return false;return true;
}void dfs(int u)
{ans.push_back(u);for(int i=0;i<node[u].size();i++){int v=node[u][i];if(vis[v])continue;vis[v]=true;dfs(v);}
} int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);init();int n,st=N-1,ed=st-1;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",a+i);for(int i=1;i<=n;i++){if(a[i]&1)addedge(st,i,2);elseaddedge(i,ed,2);}for(int i=1;i<=n;i++)//枚举奇数 {if(a[i]&1){for(int j=1;j<=n;j++)//枚举偶数 {if(a[j]&1)continue;if(is_pri(a[i]+a[j]))addedge(i,j,1);}}}if(solve(st,ed)==n){for(int i=1;i<=n;i++)//枚举奇数点 {if(a[i]&1){for(int j=head[i];j!=-1;j=edge[j].next)//枚举每条边 {if(1<=edge[j].to&&edge[j].to<=n&&edge[j].w==0)//记录哪些边被经过了 {int u=i,v=edge[j].to;node[u].push_back(v);node[v].push_back(u);}}}}memset(vis,false,sizeof(vis));int tot=0;//记录多少个环 for(int i=1;i<=n;i++){if(!vis[i]){vis[i]=true;dfs(i);tot++;}}printf("%d\n",tot);memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++){if(!vis[i]){ans.clear();vis[i]=true;dfs(i);printf("%d ",ans.size());for(int j=0;j<ans.size();j++)printf("%d ",ans[j]);printf("\n");}}}elseputs("Impossible");return 0;
}

CodeForces - 510E Fox And Dinner(最大流+奇偶建边+路径打印)相关推荐

  1. 洛谷 - P3356 火星探险问题(最大费用最大流+拆点+路径打印)

    题目链接:点击查看 题目大意:给出一个n*m的矩阵,每个点都有一个数字: 0:平坦无障碍 1:障碍 2:石块 现在在点(1,1)处有k个探测车,他们都要去往点(n,m)处,探测车只能向下或向右行驶,现 ...

  2. 洛谷 - P3254 圆桌问题(最大流+路径打印)

    题目链接:点击查看 题目大意:n个单位的员工来吃饭,每个单位有ai名员工,现在有m张桌子,每张桌子能容纳bi个人,现在要求将每个员工分配到桌子上用餐,需要满足的一个要求是每张桌子上不能有相同单位的两个 ...

  3. 洛谷 - P2764 最小路径覆盖问题(最大流+二分图最小路径覆盖+路径打印)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的有向无环图,现在需要我们求最少可以将n个点分为多少条简单路径,并打印出每一条路径 题目分析:题意挺难懂的..简单来说就是让求二分图最小路径覆 ...

  4. 洛谷 - P2763 试题库问题(最大流+路径打印)

    题目链接:点击查看 题目大意:给出n种试题类型,以及m种试题,现在需要出题,要求每种类型的题目必须满足相应的数目,问应该怎么设计方案 题目分析:一开始其实就建好了图,然后就在怀疑自己建图的正确性,因为 ...

  5. POJ2446-Chessboard【最大匹配,二分图,奇偶建图】

    正题 大意 一个n*m的棋盘上有k个洞,将1*2的木条放在上面,不能铺在洞上,不能重叠,求能不能铺满整个棋盘. 解题思路 用点来建立二分图,然后求最大匹配. 但是奇偶建图会快两倍.奇偶建图就是相邻的块 ...

  6. Codeforces 510 E. Fox And Dinner

    题目链接:http://codeforces.com/problemset/problem/510/E 乍一看和那啥魔术球问题有点神似啊/XD 其实是不一样的. 解决这道问题的关键在于发现若是相邻的两 ...

  7. CodeForces 389A Fox and Number Game

    链接:http://codeforces.com/problemset/problem/389/A Fox and Number Game time limit per test:1 second m ...

  8. Codeforces 362E Petya and Pipes 费用流建图

    题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边 ...

  9. CodeForces - 1360G A/B Matrix(最大流)

    题目链接:点击查看 题目大意:给出一个 n * m 大小的空矩阵,要求在某些位置放置 1 ,其余位置放置 0 ,使得每行都有恰好 a 个 1 ,且每列恰好有 b 个 1 ,给出一种构造方案或者判断是否 ...

最新文章

  1. asp.net开源CMS推荐
  2. PV、UV、IP的区别
  3. cacti sendmail发送告警邮件
  4. redis和kafka比较
  5. WSDM 2022 | 点击率模型特征交叉方向的发展及CAN模型介绍
  6. JVM内存结构 VS Java内存模型 VS Java对象模型
  7. ACL’22 | 为大模型定制的数据增强方法FlipDA,屠榜六大NLU 数据集!
  8. 1000道Python题库系列分享23(61个填空题)
  9. oracle 执行顺序 select查询优化
  10. 每天一道剑指offer-丑数
  11. Ruby Tip:定义索引操作符
  12. c语言口袋妖怪代码大全,口袋妖怪代码大全.docx
  13. 阿里云搭建MQTT物联网服务器
  14. Concis组件库封装——Collapse折叠面板
  15. c语言韦达定理求方程解,高一上韦达定理,高次,多元方程解法.doc
  16. Canonical标签怎么使用,Canonical标签有什么作用?
  17. C语言 计算BMI值,建议体重
  18. 语句摘抄——第19周
  19. 显示12306服务器处理中正在排队,12306排队等待中怎么回事_12306排队等待时间_12306一直在排队解决方法...
  20. 人家出轨你为什么那么嗨

热门文章

  1. Nacos源码BeatTask
  2. spring Aop的概念
  3. BeanFactoryPostProcessor执行时间
  4. 上传图片-服务端-创建文件系统服务工程
  5. Request_获取请求头数据
  6. SpringBoot创建SpringBoot项目以及启动器讲解
  7. 构建eureka高可用服务
  8. Oracle之用户操作
  9. Netty--Future和Promise
  10. 解决IntelliJ IDEA报错:调用方法[manageApp]时发生异常java.lang.IllegalStateException: 启动子级时出错