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 ...
随机推荐
- JDBC 学习笔记(二)—— 大数据+存储过程+批处理+事务管理
本文目录: 1.使用JDBC处理大数据 2.使用JDBC处理大文本 3.使用JDBC处理二进制数据 4.Oracle中大数据处理 5 ...
- check environment var
田+R cmd set XXX check environment var
- PHP之mysql_real_escape_string()函数讲解
定义和用法 mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符. 下列字符受影响: \x00 \n \r \ ' " \x1a 如果成功, ...
- unity3d旋转摄像机脚本
void Update () { )) { if (axes == RotationAxes.MouseXAndY) { // Read the mouse input axis rotationX ...
- Selenium如何使用自定义的Firefox配置文件?
一.自动保存文件 import os from selenium import webdriver fp = webdriver.FirefoxProfile() fp.set_preference( ...
- Ubuntu环境下利用ant编译nutch2.2.1 & 配置nutch2.2.1
/×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...
- [SQL Server系] -- 约束
什么是约束? 约束(Constraint)是SQL Server中提供的 自动保存数据库完整性 的一种方法,定义了可输入表或表的列中的数据限制条件. SQL Server中共有5中约束 PRIMARY ...
- codeforces D
D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...
- lintcode:最大子数组差
题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1], ...
- 自旋锁spin_lock和raw_spin_lock
自旋锁spin_lock和raw_spin_lock Linux内核spin_lock.spin_lock_irq 和 spin_lock_irqsave 分析 http://blog.csdn.ne ...