网络流。

原点到偶数连边,容量为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. caffe卷积输入通道如何到输出通道

    今天一个同学问 卷积过程好像是对 一个通道的图像进行卷积, 比如10个卷积核,得到10个feature map, 那么输入图像为RGB三个通道呢,输出就为 30个feature map 吗, 答案肯定 ...

  2. 后台数据download成excel的方法(controller/action)

    jsp页面端 <a href="/portal/server/importExec" title="Data Download"> <img ...

  3. VG、LV、rezise2fs、lvresize、fuer使用说明

    南沙节点改变LV大小,参考鸟哥第 570页 1.# resize2fs /dev/mapper/vg_niotsvr3-lv_home 150G resize2fs 1.41.12 (17-May-2 ...

  4. Explain of Interaction Operators in UML?

    来源于:EA 中的 Interaction Operators Enterprise Architect User Guide Operator Action alt Divide up intera ...

  5. CASE WHEN的两种格式

    CASE WHEN的两种格式 1.简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END 2.Case搜索函数 CASE ...

  6. 字符串查找 cmd find命令

    find /i "ora-" *.log 我对findstr是如此的依赖,以至于当我向各位讲解find命令的时候,我还得老老实实地在cmd窗口中敲下 find /? 这条命令,然后 ...

  7. 【单源最短路】dijstra poj 1502

    #include <cstdio> #include <iostream> #include <stdlib.h> #include <memory.h> ...

  8. Ubuntu下修改DNS重启也能用的方法

    1.通过修改:/etc/resolvconf/resolv.conf.d/base(这个文件默认是空的)实现 内容填上需要修改的nameserver

  9. jquery 简单的栏目切换

    <style> ul{ list-style:none; padding:0px; margin:0px;} #nav_box{ width:502px; height:402px; ov ...

  10. HUD 1541/BIT(数状数组)

    题目链接 /* 按从左到右,从下到上的顺序给出星星的坐标,计算出level为[0,n)的星星的个数. 星星的level为该星星左下边(包括自己正下方的星星,但是不包括自己)星星的个数. BIT模板题. ...