网络流。

原点到偶数连边,容量为2,

奇数到汇点连边,容量为2,

偶数到与之能凑成素数的奇数连边,容量为1

如果奇数个数不等于偶数个数,输出不可能

如果原点到偶数的边不满流,输出不可能

剩下的情况有解:因为一个偶数点选了两个奇数点,一个奇数点被两个偶数点选择,一定能构造出环。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std; const int maxn = + ;
const int INF = 0x7FFFFFFF;
struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int n, m, s, t;
int num[maxn]; vector<int>g[maxn];
vector<int> ans[maxn];
bool f[maxn];
int block; void init()
{
for (int i = ; i < maxn; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
int w = edges.size();
G[from].push_back(w - );
G[to].push_back(w - );
}
bool BFS()
{
memset(vis, , sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = ; i<G[x].size(); i++)
{
Edge e = edges[G[x][i]];
if (!vis[e.to] && e.cap>e.flow)
{
vis[e.to] = ;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a)
{
if (x == t || a == )
return a;
int flow = , f;
for (int &i = cur[x]; i<G[x].size(); i++)
{
Edge e = edges[G[x][i]];
if (d[x]+ == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
edges[G[x][i]].flow+=f;
edges[G[x][i] ^ ].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
if(!flow) d[x] = -;
return flow;
}
int dinic(int s, int t)
{
int flow = ;
while (BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
return flow;
} bool prime(int x)
{
for(int i=;i*i<=x;i++)
if(x%i==) return ;
return ;
} void Find(int now)
{
f[now]=;
ans[block].push_back(now);
for(int i=;i<g[now].size();i++)
{
if(f[g[now][i]]) continue;
Find(g[now][i]);
}
} int main()
{
while(~scanf("%d",&n))
{
for(int i=;i<=n;i++) scanf("%d",&num[i]);
init();
s=;t=n+; int e1=,e2=;
int flag=;
for(int i=;i<=n;i++)
{
if(num[i]%==) { e1++; AddEdge(s,i,); }
else { e2++; AddEdge(i,t,); }
}
if(e1!=e2) flag=;
else
{
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(num[i]%==&&num[j]%==&&prime(num[i]+num[j]))
AddEdge(i,j,);
int Flow=dinic(s,t);
if(Flow!=*e1) flag=;
}
if(flag==) printf("Impossible\n");
else
{
block=; memset(f,,sizeof f);
for(int i=;i<maxn;i++) { g[i].clear(); ans[i].clear(); }
for(int i=;i<edges.size();i=i+)
{
if(edges[i].flow==)
{
int u=edges[i].from;
int v=edges[i].to;
g[u].push_back(v);
g[v].push_back(u);
}
} for(int i=;i<=n;i++)
{
if(f[i]) continue;
Find(i); block++;
} printf("%d\n",block);
for(int i=;i<block;i++)
{
printf("%d ",ans[i].size());
for(int j=;j<ans[i].size();j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
}
return ;
}

CodeForces 510E Fox And Dinner的更多相关文章

  1. codeforces 510E. Fox And Dinner 网络流

    题目链接 给出n个人, 以及每个人的值, 要求他们坐在一些桌子上面, 每个桌子如果有人坐, 就必须做3个人以上. 并且相邻的两个人的值加起来必须是素数.每个人的值都>=2. 由大于等于2这个条件 ...

  2. Codeforces Round #290 (Div. 2) E. Fox And Dinner 网络流建模

    E. Fox And Dinner time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  3. CF510E. Fox And Dinner

    CF510E. Fox And Dinner https://codeforces.com/contest/510 分析: 由于\(a_i>2\), 相邻两个数一定一奇一偶,按奇偶建立二分图. ...

  4. 网络流 I - Fox And Dinner CodeForces - 510E

    Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). T ...

  5. Fox And Dinner CodeForces - 510E (最大流)

    大意: n只狐狸, 要求分成若干个环, 每个环的狐狸不少于三只, 相邻狐狸年龄和为素数. 狐狸年龄都>=2, 那么素数一定为奇数, 相邻必须是一奇一偶, 也就是一个二分图, 源点向奇数点连容量为 ...

  6. 网络流(最大流)CodeForces 512C:Fox And Dinner

    Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). T ...

  7. Codeforces 510 E. Fox And Dinner

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

  8. CodeForces Round #290 Fox And Dinner

    而是Div2的最后一题,当时打比赛的时候还不会最大流.自己能够把它写出来然后1A还是很开心的. 题意: 有n个不小于2的整数,现在要把他们分成若干个圈.在每个圈中,数字的个数不少于3个,而且相邻的两个 ...

  9. 【Codeforces】512C Fox and Dinner

    [解析]欧拉筛法,奇偶分析.建二分图,网络流 [Analysis] http://blog.csdn.net/qq574857122/article/details/43453087. 所谓的连通块就 ...

随机推荐

  1. restlet不能接受angular post过来的数据

    修改header create: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded'} }

  2. 关于用模拟器运行百度地图API无法定位的问题 - 不能用模拟器

    模拟器是没有办法定位,当你加入定位模块的时候,传出的参数都是空的. 定位的这个方法函数,是通过回调接口来实现,而且触发该事件的时候,需要经纬度位置改变.官方文档写得很清楚,简单点来说,就是你没有GPS ...

  3. 关于PHP执行超时的问题

    PHP配置文件的参数max_execution_time表示脚本执行超时时间 max_execution_time=0表示不限制 max_execution_time=2表示执行两秒后终止,同时报错F ...

  4. wpa_supplicant wpa_cli 的使用说明

    wpa_supplicant -d -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -iwlan0 -B   会在/data/misc/wifi/下产生 ...

  5. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  6. UVA - 10635 最长公共子序列

    input n,p,q 2<=n<=250 1<=p,q<=n*n 1 a1 a2 a3 ... ap 1<ai<n*n,ai!=aj 1 b1 b2 b3 ... ...

  7. PHP全选择删除功能

    <script type="text/javascript" language="javascript"> function selectBox(s ...

  8. c++模板两个数的加法

    1.最简单的情况: template<class T> T Add(const T& a, const T& b) { return a + b; } 缺点是不能够处理不同 ...

  9. Swift 与 JSON 数据 浅析

    转载自:http://www.cnblogs.com/theswiftworld/p/4660177.html 我们大家平时在开发 App 的时候,相信接触最多的就是 JSON 数据了.只要你的 Ap ...

  10. java内部类继承--构造函数传参

    /: innerclasses/InheritInner.java // Inheriting an inner class. class WithInner { class Inner {} } / ...