codeforces 512C (最大流)
2016-10-20 21:42
239 查看
题目链接:点击这里
题意:安排n个人在圆桌吃饭,每个人有一个值,任意相邻的两个人的值的和必须为质数,一张桌子至少坐3个人。然后求出任意的方案。每个数都大于2,要让相邻两个的和为质数,必须是一奇一偶。所以只需要每一个奇数左右两个偶数不相同就可以使得一张桌子至少3个人(3个人的桌子是不可能的,至少是4个人)。所以直接按照二分图建模,S到每一个奇数,流量为2,表示每个奇数相邻两个偶数;奇数到和他相加为质数的偶数,流量为1;偶数到T,流量为2;最后在残留网络上找方案,一个联通分量是一个方案。
#include <bits/stdc++.h> using namespace std; #define maxn 205 #define maxm 20005 #define type int #define INF 1e8 int n, m; int s, t; struct Edge { int from, to, next; type cap, flow; void get (int u, int a, int b, type c, type d) { from = u; to = a; next = b; cap = c; flow = d; } }edge[maxm]; int tol; int head[maxn]; int gap[maxn], dep[maxn], pre[maxn], cur[maxn]; bool is_prime[maxm]; void init () { memset (is_prime, 1, sizeof is_prime); is_prime[0] = is_prime[1] = 0; for (int i = 2; i < maxm; i++) if (is_prime[i]) { for (int j = i+i; j < maxm; j += i) is_prime[j] = 0; } tol = 0; memset (head, -1, sizeof head); } void add_edge (int u, int v, type w, type rw=0) { edge[tol].get(u, v,head[u],w,0);head[u]=tol++; edge[tol].get(v, u,head[v],rw,0);head[v]=tol++; } type sap (int start, int end, int N) { memset (gap, 0, sizeof gap); memset (dep, 0, sizeof dep); memcpy (cur, head, sizeof head); int u = start; pre[u] = -1; gap[0] = N; type ans = 0; while (dep[start] < N) { if (u == end) { type Min = INF; for (int i = pre[u]; i != -1; i = pre[edge[i^1].to]) if (Min > edge[i].cap - edge[i].flow) Min = edge[i].cap-edge[i].flow; for (int i = pre[u]; i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for (int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if (edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if (flag) { u = v; continue; } int Min = N; for (int i = head[u]; i != -1; i = edge[i].next) if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if (!gap[dep[u]]) return ans; dep[u] = Min+1; gap[dep[u]]++; if (u != start) u = edge[pre[u]^1].to; } return ans; } int a[maxn], k; vector <int> table[maxn], con[maxn]; bool vis[maxn]; void dfs (int u) { if (vis[u]) return ; table[k].push_back (u); vis[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].flow && !vis[v]) { table[k].push_back (v); vis[v] = 1; dfs (con[v][0] == u ? con[v][1] : con[v][0]); break; } } } int main () { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; con[i].clear (); } init (); int N; s = 0, t = n+1, N = t+1; int odd = 0, even = 0; for (int i = 1; i <= n; i++) { if (a[i]&1) { odd++; add_edge (s, i, 2); for (int j = 1; j <= n; j++) if (a[j]%2 == 0 && is_prime[a[i]+a[j]]) { add_edge (i, j, 1); } } else { even++; add_edge (i, t, 2); } } if (odd != even) { cout << "Impossible" << endl; return 0; } int ans = sap (s, t, N); if (ans != even*2) { cout << "Impossible" << endl; return 0; } k = 0; memset (vis, 0, sizeof vis); for (int i = 1; i <= n; i++) if (a[i]&1) { for (int j = head[i]; j != -1; j = edge[j].next) { int v = edge[j].to; if (edge[j].flow) { con[v].push_back (i); } } } for (int i = 1; i <= n; i++) if ((a[i]&1) && !vis[i]) { table[++k].clear (); dfs (i); } cout << k << endl; for (int i = 1; i <= k; i++) { int sz = table[i].size (); cout << sz << " "; for (int j = 0; j < sz; j++) { cout << table[i][j] << (j == sz-1 ? '\n' : ' '); } } return 0; }
相关文章推荐
- 网络流(最大流)CodeForces 512C:Fox And Dinner
- CodeForces 578C Weakness and Poorness(三分法+最大子段和)
- CodeForces 682E Alyona and Triangles【最大三角形 旋转卡壳or迭代】
- CodeForces 498C Array and Operations(最大流)
- codeforces 839 E. Mother of Dragons(最大团)
- (最大流)CodeForces - 499E Array and Operations
- 最大流 Fox And Dinner : CodeForces - 510E
- CodeForces 498C Array and Operations 最大流
- Codeforces 75D Big Maximum Sum 最大子段和 dp
- Codeforces 498C Array and Operations(最大流)
- CodeForces - 892C Pride (n个数,求相邻两个数的最大公约数替换其中一个数,看要操作几次使得n个数全部变成1)
- CodeForces Div124-1 hrbust 1474 哈理工oj 求字典序最大的子串【贪心】
- CodeForces - 150C :Smart Cheater (线段树,求最大连续区间)
- 网络流(最大流):CodeForces 499E Array and Operations
- Codeforces--653D--Delivery Bears(二分+最大流)
- 【codeforces】-#621-AWet Shark and Odd and Even(n个数最大偶数和)
- Codeforces 653D Delivery Bears 【二分+最大流】
- Codeforces 706D Vasiliy's Multiset (字典树求异或最大值)
- Codeforces 546E Soldier and Traveling(最大流)
- [无源汇最大费用可行流 差分费用流] Codeforces 717G Bubble Cup 9 - Finals G. Underfail