而是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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. 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 ...

  5. 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 ...

  6. Codeforces Round #290 (Div. 2) B. Fox And Two Dots(DFS)

    http://codeforces.com/problemset/problem/510/B #include "cstdio" #include "cstring&qu ...

  7. DFS Codeforces Round #290 (Div. 2) B. Fox And Two Dots

    题目传送门 /* DFS:每个点四处寻找,判断是否与前面的颜色相同,当走到已走过的表示成一个环 */ #include <cstdio> #include <iostream> ...

  8. 找规律 Codeforces Round #290 (Div. 2) A. Fox And Snake

    题目传送门 /* 水题 找规律输出 */ #include <cstdio> #include <iostream> #include <cstring> #inc ...

  9. 拓扑排序 Codeforces Round #290 (Div. 2) C. Fox And Names

    题目传送门 /* 给出n个字符串,求是否有一个“字典序”使得n个字符串是从小到大排序 拓扑排序 详细解释:http://www.2cto.com/kf/201502/374966.html */ #i ...

随机推荐

  1. JDBC 学习笔记(二)—— 大数据+存储过程+批处理+事务管理

    本文目录:       1.使用JDBC处理大数据        2.使用JDBC处理大文本        3.使用JDBC处理二进制数据        4.Oracle中大数据处理        5 ...

  2. check environment var

    田+R cmd set XXX check environment var

  3. PHP之mysql_real_escape_string()函数讲解

    定义和用法 mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符. 下列字符受影响: \x00 \n \r \ ' " \x1a 如果成功, ...

  4. unity3d旋转摄像机脚本

    void Update () { )) { if (axes == RotationAxes.MouseXAndY) { // Read the mouse input axis rotationX ...

  5. Selenium如何使用自定义的Firefox配置文件?

    一.自动保存文件 import os from selenium import webdriver fp = webdriver.FirefoxProfile() fp.set_preference( ...

  6. Ubuntu环境下利用ant编译nutch2.2.1 & 配置nutch2.2.1

    /×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...

  7. [SQL Server系] -- 约束

    什么是约束? 约束(Constraint)是SQL Server中提供的 自动保存数据库完整性 的一种方法,定义了可输入表或表的列中的数据限制条件. SQL Server中共有5中约束 PRIMARY ...

  8. codeforces D

    D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...

  9. lintcode:最大子数组差

    题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1], ...

  10. 自旋锁spin_lock和raw_spin_lock

    自旋锁spin_lock和raw_spin_lock Linux内核spin_lock.spin_lock_irq 和 spin_lock_irqsave 分析 http://blog.csdn.ne ...