codeforces 512C (最大流)
来源:互联网 发布:园林设计专业知乎 编辑:程序博客网 时间:2024/05/19 13:18
题目链接:点击这里
题意:安排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 1e8int 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;}
0 0
- codeforces 512C (最大流)
- codeforces 498C C. Array and Operations(最大流+数论)
- codeforces 498C C. Array and Operations(最大流+数论)
- CodeForces 498C Array and Operations(最大流)
- CodeForces 498C Array and Operations 最大流
- Codeforces 723C暴力(最小值最大)
- codeforces 546E (最大流)
- Codeforces Round #284 (Div. 1) C. Array and Operations(网络流‘最大流)
- Codeforces Round #284 (Div. 1) C. Array and Operations (最大流)
- [c++]最大流算法
- codeforces 277E 最小费用最大流
- codeforces 78E - Evacuation 最大流
- codeforces 653D (二分 最大流)
- 最大流 Fox And Dinner : CodeForces
- Codeforces 164C 费用流
- Codeforces 546E - Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling (最大流)
- Codeforces 546E:士兵的旅行 最大网络流
- 【openjudge 计算概论(A)】[基础编程练习(控制成分)]
- poj2299Ultra-QuickSort(树状数组+离散化)
- python中使用elasticsearch做为搜索引擎
- Micro Focus COBOL multi-thread programming
- LeetCode #416: Partition Equal Subset Sum
- codeforces 512C (最大流)
- 税控盘发票查询系统
- uva11572
- Java知识结构图谱
- Retrofit系列一
- vs2015.NET4.5中文智能提示问题
- poj之旅——1018
- 准备学习Android了!
- Hibernate各种主键生成策略与配置详解