CodeForces Round #290 Fox And Dinner
而是Div2的最后一题,当时打比赛的时候还不会最大流。自己能够把它写出来然后1A还是很开心的。
题意:
有n个不小于2的整数,现在要把他们分成若干个圈。在每个圈中,数字的个数不少于3个,而且相邻的两个数之和是质数。
分析:
因为每个数都不小于2,所以相加得到的质数一定是奇数,那么在某个圈中,一定是奇偶相间的。
也就是 奇数相邻的两个数是偶数,偶数相邻的两个数是奇数。
所以一个圈中的数字一定是偶数个,所有的输入中也必须是偶数和奇数的个数相同才可能有解。
这转化为了二分图匹配,其中X是奇数,Y是偶数,如果X和Y中的两个数加起来是质数,则连一条容量为1的边。
因为每个奇数的两边是偶数,所以将X中的点与源点连一条容量为2的边。
同样地,将Y中的点与汇点连一条容量为2的边。
求一次最大流,如果满载也就是流量为n的话,说明有解。
输出解:可以根据求解最大流的时候,找到的路径,再建一个图,然后DFS找环。
#include <bits/stdc++.h> using namespace std; const int maxn = + ;
const int INF = ; struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f): from(u), to(v), cap(c), flow(f) {}
}; struct EdmondsKarp
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn]; //可改进量
int p[maxn]; //上一条弧 void Init(int n)
{
for(int i = ; i < n; ++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, , ));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} int MaxFlow(int s, int t)
{
int flow = ;
for(;;)
{
memset(a, , sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty())
{
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); ++i)
{
Edge& e = edges[G[x][i]];
if(!a[e.to] && e.cap > e.flow)
{
a[e.to] = min(a[x], e.cap - e.flow);
p[e.to] = G[x][i];
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
flow += a[t];
}
return flow;
}
}g; int a[maxn], odd[maxn], even[maxn], p1, p2;
vector<int> G[maxn], ans[maxn];
const int maxp = ;
bool prime[maxp + ], vis[maxn]; void prime_table()
{
int m = sqrt(maxp + 0.5);
for(int i = ; i <= m; ++i) if(!prime[i])
for(int j = i*i; j <= maxp; j += i) prime[j] = true;
} void find_circle(int cnt, int u)
{
ans[cnt].push_back(u);
vis[u] = true;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(!vis[v]) find_circle(cnt, v);
}
} int main()
{
//freopen("in.txt", "r", stdin); int n;
scanf("%d", &n);
g.Init(n+);
for(int i = ; i <= n; ++i)
{
scanf("%d", &a[i]);
if(a[i] & ) odd[p1++] = i;
else even[p2++] = i;
}
if(p1 != p2) { puts("Impossible"); return ; }//奇数和偶数个数不同 for(int i = ; i < p1; ++i)
{
g.AddEdge(, odd[i], );
g.AddEdge(even[i], n+, );
} prime_table();
for(int i = ; i < p1; ++i)
for(int j = ; j < p1; ++j)
if(!prime[ a[odd[i]] + a[even[j]] ])
g.AddEdge(odd[i], even[j], ); int flow = g.MaxFlow(, n+);
if(flow != n) { puts("Impossible"); return ; } for(int i = ; i < g.edges.size(); ++i)
{//为了寻找路径,建一个新图
Edge& e = g.edges[i];
if(e.cap == && e.flow == )
{
G[e.from].push_back(e.to);
G[e.to].push_back(e.from);
}
} int cnt = ;
for(int i = ; i <= n; ++i) if(!vis[i]) find_circle(cnt++, i); printf("%d\n", cnt);
for(int i = ; i < cnt; ++i)
{
printf("%d %d", ans[i].size(), ans[i][]);
for(int j = ; j < ans[i].size(); ++j) printf(" %d", ans[i][j]);
puts("");
} return ;
}
代码君
CodeForces Round #290 Fox And Dinner的更多相关文章
- 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 ...
- Codeforces Round #290 (Div. 2) D. Fox And Jumping dp
D. Fox And Jumping 题目连接: http://codeforces.com/contest/510/problem/D Description Fox Ciel is playing ...
- Codeforces Round #290 (Div. 2) C. Fox And Names dfs
C. Fox And Names 题目连接: http://codeforces.com/contest/510/problem/C Description Fox Ciel is going to ...
- Codeforces Round #290 (Div. 2) B. Fox And Two Dots dfs
B. Fox And Two Dots 题目连接: http://codeforces.com/contest/510/problem/B Description Fox Ciel is playin ...
- Codeforces Round #290 (Div. 2) A. Fox And Snake 水题
A. Fox And Snake 题目连接: http://codeforces.com/contest/510/problem/A Description Fox Ciel starts to le ...
- Codeforces Round #290 (Div. 2) B. Fox And Two Dots(DFS)
http://codeforces.com/problemset/problem/510/B #include "cstdio" #include "cstring&qu ...
- DFS Codeforces Round #290 (Div. 2) B. Fox And Two Dots
题目传送门 /* DFS:每个点四处寻找,判断是否与前面的颜色相同,当走到已走过的表示成一个环 */ #include <cstdio> #include <iostream> ...
- 找规律 Codeforces Round #290 (Div. 2) A. Fox And Snake
题目传送门 /* 水题 找规律输出 */ #include <cstdio> #include <iostream> #include <cstring> #inc ...
- 拓扑排序 Codeforces Round #290 (Div. 2) C. Fox And Names
题目传送门 /* 给出n个字符串,求是否有一个“字典序”使得n个字符串是从小到大排序 拓扑排序 详细解释:http://www.2cto.com/kf/201502/374966.html */ #i ...
随机推荐
- 写一个EF的CodeFirst的Demo
写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...
- anroid ndk编译ffmpeg 引用librtmp libx264
Ffmpeg 无处不在,自然android系统少不了它,折腾了不少时间完成 ndk编译ffmpeg,生成so库中引用了外部库librtmp,libx264.条条大路通罗马, 也许还有别的更好的方法去完 ...
- jquery插件dataTables添加序号列
官网方法实例: $(document).ready(function() { var t = $('#example').DataTable({ "columnDef ...
- Java7 新特性 数值文本表示法
今天和大家分享下 java7中新特性-数值文本表示法 首先,在原来jdk1.6中 如果需要将一个二进制的数值转换成十进制的话,一般情况下都会以下面的代码方式去实现. public static voi ...
- Node.js 随记
http://nodejs.org/ 下载并安装 node.js 最新版本 运行cmd,输入npm install xxxxxx 回车,安装扩展模块,如:express,socket.io等 运行c ...
- [转载]C++ CString与int 互转
1.CString 转 int CString strtemp = "100"; int intResult; intResult= atoi(strtem ...
- 配置java环境
1.下载JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 2.下载之后ne ...
- HDU4276 The Ghost Blows Light SPFA&&树dp
题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739 做这道题主要是为了加强自己对SPFA的代码的训练 ...
- mybatis 插入日期类型精确到秒的有关问题
mybatis 插入日期类型精确到秒的问题 Mybatis 插入 数据库是为了防止插入空时报错, Mybatis 提供了一套机制,只要给定插入的字段的类型,如果为空,则它会自动处理为相应类型的默认值: ...
- Android开发--Activity生命周期回顾理解
Activity和Servlet一样,都用了回调机制.我们通过类比servlet来学习Activity.当一个servlet开发出来之后,该servlet运行于Web服务器中.服务器何时创建servl ...