hdu - 4888 - Redraw Beautiful Drawings(最大流)
来源:互联网 发布:c语言高级编程是什么 编辑:程序博客网 时间:2024/06/05 05:36
题意:给一个N行M列的数字矩阵的行和以及列和,每个元素的大小不超过K,问这样的矩阵是否存在,是否唯一,唯一则求出各个元素N(1 ≤ N ≤ 400) , M(1 ≤ M ≤ 400), K(1 ≤ K ≤ 40)。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888
——>>建图:
1)超级源S = 0,超级汇T = N + M + 1;
2)S到每个行和各连一条边,容量为该行行和;
3)每个行和到每个列和各连一条边,容量为K;
4)每个列和到 T 各连一条边,容量为该列列和。
一个行到所有列连边,为的是让该行分流多少给各个列,正是该行某列元素的大小。。
所以,如果 S 到 T 的最大流 == 所有元素的和,则说明有解。。
残量网络中的行列结点之间如果有长度 > 2 的环(自环长度为2,但无法调整流量),则说明这个环中的流量可以调整,使得达到最大流时该环上的流量不唯一,即矩阵不唯一。。
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using std::min;using std::queue;const int MAXN = 400 * 2 + 10;const int MAXM = 400 * 400 + 2 * MAXN;const int INF = 0x3f3f3f3f;struct EDGE{ int to; int cap; int flow; int nxt;} edge[MAXM << 1];int N, M, K;int sum;int S, T;int hed[MAXN], ecnt;int cur[MAXN], h[MAXN];bool impossible, bUnique;void Init(){ impossible = false; bUnique = true; ecnt = 0; memset(hed, -1, sizeof(hed));}void AddEdge(int u, int v, int cap){ edge[ecnt].to = v; edge[ecnt].cap = cap; edge[ecnt].flow = 0; edge[ecnt].nxt = hed[u]; hed[u] = ecnt++; edge[ecnt].to = u; edge[ecnt].cap = 0; edge[ecnt].flow = 0; edge[ecnt].nxt = hed[v]; hed[v] = ecnt++;}bool Bfs(){ memset(h, -1, sizeof(h)); queue<int> qu; qu.push(S); h[S] = 0; while (!qu.empty()) { int u = qu.front(); qu.pop(); for (int e = hed[u]; e != -1; e = edge[e].nxt) { int v = edge[e].to; if (h[v] == -1 && edge[e].cap > edge[e].flow) { h[v] = h[u] + 1; qu.push(v); } } } return h[T] != -1;}int Dfs(int u, int cap){ if (u == T || cap == 0) return cap; int flow = 0, subFlow; for (int e = cur[u]; e != -1; e = edge[e].nxt) { cur[u] = e; int v = edge[e].to; if (h[v] == h[u] + 1 && (subFlow = Dfs(v, min(cap, edge[e].cap - edge[e].flow))) > 0) { flow += subFlow; edge[e].flow += subFlow; edge[e ^ 1].flow -= subFlow; cap -= subFlow; if (cap == 0) break; } } return flow;}int Dinic(){ int maxFlow = 0; while (Bfs()) { memcpy(cur, hed, sizeof(hed)); maxFlow += Dfs(S, INF); } return maxFlow;}void Read(){ int r, c; int rsum = 0, csum = 0; S = 0; T = N + M + 1; for (int i = 1; i <= N; ++i) { scanf("%d", &r); rsum += r; AddEdge(S, i, r); } for (int i = 1; i <= M; ++i) { scanf("%d", &c); csum += c; AddEdge(i + N, T, c); } if (rsum != csum) { impossible = true; return; } sum = rsum; for (int i = 1; i <= N; ++i) { for (int j = M; j >= 1; --j) { AddEdge(i, j + N, K); } }}void CheckPossible(){ if (impossible) return; if (Dinic() != sum) { impossible = true; }}bool vis[MAXN];bool CheckCircle(int x, int f){ vis[x] = true; for (int e = hed[x]; e != -1; e = edge[e].nxt) { if (edge[e].cap > edge[e].flow) { int v = edge[e].to; if (v == f) continue; if (vis[v]) return true; else { if (CheckCircle(v, x)) return true; } } } vis[x] = false; return false;}void CheckUnique(){ if (impossible) return; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= N; ++i) { if (CheckCircle(i, -1)) { bUnique = false; return; } }}void Output(){ if (impossible) { puts("Impossible"); } else if (!bUnique) { puts("Not Unique"); } else { puts("Unique"); for (int i = 1; i <= N; ++i) { for (int e = hed[i], j = 1; e != -1 && j <= M; e = edge[e].nxt, ++j) { printf("%d", edge[e].flow); if (j < M) { printf(" "); } } puts(""); } }}int main(){ while (scanf("%d%d%d", &N, &M, &K) == 3) { Init(); Read(); CheckPossible(); CheckUnique(); Output(); } return 0;}
1 0
- hdu 4888 Redraw Beautiful Drawings(最大流)
- hdu 4888 Redraw Beautiful Drawings 最大流
- hdu 4888 Redraw Beautiful Drawings(最大流)
- HDU 4888 Redraw Beautiful Drawings(最大流)
- hdu 4888 Redraw Beautiful Drawings (最大流)
- hdu - 4888 - Redraw Beautiful Drawings(最大流)
- HDU 4888 Redraw Beautiful Drawings 最大流判满流
- hdu 4888 Redraw Beautiful Drawings(最大流,判环)
- hdu 4888 Redraw Beautiful Drawings 最大流唯一性判断
- HDU 4888 Redraw Beautiful Drawings 最大流(唯一性)
- [HDOJ 4888] Redraw Beautiful Drawings [最大流]
- HDU -- 4888 Redraw Beautiful Drawings(最大流,判断最大流唯一性)
- Hdu-4888 Redraw Beautiful Drawings 网络流
- HDU 4888 (杭电多校#3)Redraw Beautiful Drawings(网络流之最大流)
- hdu 4888 Redraw Beautiful Drawings(Dinic最大流+判断有没有环)
- Hdu 4888 Redraw Beautiful Drawings(最大流+方案唯一判断)
- HDU 4888 Redraw Beautiful Drawings 网络流(矩阵模型)
- hdu 4888 Redraw Beautiful Drawings
- .net CHARTING图表控件免费下载地址
- android 备忘录之简单实现
- LBP原理介绍以及算法实现
- tp自定义函数使用
- “fatal error C1083: ”无法打开包括文件 排查思路
- hdu - 4888 - Redraw Beautiful Drawings(最大流)
- 正向代理、反向代理
- Android 如何收集已发布程序的崩溃信息
- 为奴12年阅读有感
- SEO论坛的发展模式 壮大需要创意
- JavaScript深拷贝和浅拷贝
- CSS颜色代码大全
- SQLServer2008全套 数据库简介,分离,收缩,快照
- Android(Lollipop/5.0) Material Design(八) 保持兼容性