pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888

加入一个源点与汇点,建图例如以下:

1. 源点 -> 每一行相应的点,流量限制为该行的和

2. 每一行相应的点 -> 每一列相应的点,流量限制为 K

3. 每一列相应的点 -> 汇点,流量限制为该列的和

求一遍最大流,若最大流与矩阵之和相等,说明有解,否则无解。推断唯一解,是推断残量网络中是否存在一个长度大于2的环。若存在说明有多解,否则有唯一解,解就是每条边行i->列j的流量。



  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <map>
  4. #include <set>
  5. #include <stack>
  6. #include <vector>
  7. #include <math.h>
  8. #include <string.h>
  9. #include <queue>
  10. #include <string>
  11. #include <stdlib.h>
  12. #include <algorithm>
  13. #define LL long long
  14. #define _LL __int64
  15. #define eps 1e-12
  16. #define PI acos(-1.0)
  17. #define C 240
  18. #define S 20
  19. using namespace std;
  20.  
  21. const int INF = 0x3f3f3f3f;
  22.  
  23. const int maxn = 810;
  24. const int maxm = 160000+810;
  25.  
  26. struct node
  27. {
  28. int u,v,w,next;
  29. } edge[maxm << 1];
  30.  
  31. int cnt,head[maxn];
  32. int n,m,k,s,t;
  33. int nn[410],mm[410];
  34. int maxflow;
  35. int vis[maxn];
  36. int dis[maxn];
  37.  
  38. void init()
  39. {
  40. cnt = 0;
  41. memset(head,-1,sizeof(head));
  42. }
  43.  
  44. void add(int u, int v, int f)
  45. {
  46. edge[cnt] = (struct node){u,v,f,head[u]};
  47. head[u] = cnt++;
  48.  
  49. edge[cnt] = (struct node){v,u,0,head[v]};
  50. head[v] = cnt++;
  51. }
  52.  
  53. bool bfs()
  54. {
  55. queue<int>que;
  56. while(!que.empty()) que.pop();
  57. memset(dis,-1,sizeof(dis));
  58. dis[s] = 0;
  59. que.push(s);
  60.  
  61. while(!que.empty())
  62. {
  63. int u = que.front();
  64. que.pop();
  65.  
  66. for(int i = head[u]; i != -1; i = edge[i].next)
  67. {
  68. int v = edge[i].v;
  69. if(dis[v] == -1 && edge[i].w)
  70. {
  71. dis[v] = dis[u]+1;
  72. que.push(v);
  73. }
  74. }
  75. }
  76. if(dis[t] == -1)
  77. return false;
  78. return true;
  79. }
  80.  
  81. int dfs(int u, int delta)
  82. {
  83. if(u == t || delta == 0) return delta;
  84. int dd;
  85. int ret = 0;
  86. for(int i = head[u]; i != -1 && delta; i = edge[i].next)
  87. {
  88. if(dis[edge[i].v] == dis[u]+1 && (dd = dfs(edge[i].v,min(delta,edge[i].w))))
  89. {
  90. edge[i].w -= dd;
  91. edge[i^1].w += dd;
  92. delta -= dd;
  93. ret += dd;
  94. if(delta == 0)
  95. return ret;
  96. }
  97. }
  98. dis[u] = -1;
  99. return ret;
  100. }
  101.  
  102. int Dinic()
  103. {
  104. int ret = 0;
  105. while(bfs())
  106. {
  107. ret += dfs(s,INF);
  108. }
  109. return ret;
  110. }
  111.  
  112. int dfs_1(int u,int fa)
  113. {
  114. for(int i=head[u]; i!=-1; i=edge[i].next)
  115. {
  116. if(i==(fa^1)) continue;
  117. if(edge[i].w)
  118. {
  119. if(vis[edge[i].v]) return 1;
  120. vis[edge[i].v]=1;
  121. if(dfs_1(edge[i].v,i)) return 1;
  122. vis[edge[i].v]=0;
  123. }
  124. }
  125. return 0;
  126. }
  127.  
  128. void putmat()
  129. {
  130. int f[410][410];
  131. printf("Unique\n");
  132. for(int u = 1; u <= n; u++)
  133. {
  134. for(int i = head[u]; i != -1; i = edge[i].next)
  135. {
  136. int v = edge[i].v;
  137. if(v > n && v <= n+m)
  138. f[u][v-n] = k - edge[i].w;
  139. }
  140. }
  141. for(int i = 1; i <= n; i++)
  142. {
  143. for(int j = 1; j < m; j++)
  144. printf("%d ",f[i][j]);
  145. printf("%d\n",f[i][m]);
  146. }
  147. }
  148.  
  149. int main()
  150. {
  151. while(~scanf("%d %d %d",&n,&m,&k))
  152. {
  153. init();
  154. s = 0;
  155. t = n+m+1;
  156. int sum1 = 0;
  157. int sum2 = 0;
  158. for(int i = 1; i <= n; i++)
  159. {
  160. scanf("%d",&nn[i]);
  161. add(s,i,nn[i]);
  162. sum1 += nn[i];
  163. for(int j = 1; j <= m; j++)
  164. add(i,j+n,k);
  165. }
  166.  
  167. for(int i = 1; i <= m; i++)
  168. {
  169. scanf("%d",&mm[i]);
  170. add(i+n,t,mm[i]);
  171. sum2 += mm[i];
  172. }
  173.  
  174. if(sum1 != sum2)
  175. {
  176. printf("Impossible\n");
  177. }
  178.  
  179. else
  180. {
  181. maxflow = Dinic();
  182.  
  183. if(maxflow != sum1)
  184. {
  185. printf("Impossible\n");
  186. }
  187. else
  188. {
  189. int flag = 0;
  190. memset(vis,0,sizeof(vis));
  191. for(int i = 1; i <= n; i++)
  192. {
  193. if(dfs_1(i,-1))
  194. {
  195. flag = 1;
  196. break;
  197. }
  198. }
  199. if(flag == 1)
  200. printf("Not Unique\n");
  201.  
  202. else
  203. putmat();
  204. }
  205. }
  206. }
  207. return 0;
  208. }

hdu 4888 Redraw Beautiful Drawings(最大流,判环)的更多相关文章

  1. hdu4888 Redraw Beautiful Drawings 最大流+判环

    hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6553 ...

  2. hdu 4888 Redraw Beautiful Drawings 最大流

    好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...

  3. hdu 4888 Redraw Beautiful Drawings 网络流

    题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...

  4. HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)

    Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...

  5. HDU 4888 Redraw Beautiful Drawings

    网络流. $s$向每一个$r[i]$连边,容量为$r[i]$. 每一个$r[i]$向每一个$c[j]$连边,容量为$k$. 每一个$c[j]$向$t$连边容量为$c[j]$. 跑最大流,中间每一条边上 ...

  6. HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点   源点 到行连流量为 所给的 ...

  7. HDU 4888 Redraw Beautiful Drawings 网络流 建图

    题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...

  8. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  9. HDU Redraw Beautiful Drawings 推断最大流是否唯一解

    点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 ...

随机推荐

  1. Codeforces_761_E_(dfs)

    E. Dasha and Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. java项目其他基础配置

    创建完maven项目之后. 1.pom.xml文件配置项目相关的架包. 2.src.main.resources下边 创建文件夹:spring以及mapper. 3.src.main.resource ...

  3. ProgressDialog的样式

    ProgressDialog的样式有两种,一种是圆形不明确状态,一种是水平进度条状态 第一种方式:圆形进度条 final ProgressDialog dialog = new ProgressDia ...

  4. ZOJ - 3992 - One-Dimensional Maze (思维)

    题意: 一条长度为n的直线,你一开始在位置m上 其中每个整点都有一个字符'L'或'R',如果是'L'那么你必须往左走一步,否则往右走一步 如果你到达位置1或位置n你任务就完成了 不过有可能你永远到不了 ...

  5. Makefile,Shell command,Shell Language 之间的联系

    1. Makefile 首先要知道Makefile 是什么东西,Makefile 是一个指令文件,里面存储着自定义的命令(可以借助已有的命令创造而来)在不同的系统下对Makefile 的区别不一样,L ...

  6. UVA - 1619 Feel Good(扫描法)

    题目: 思路: 预处理出a[i]在哪个范围区间内是最小的,然后直接遍历a数组求答案就可以了. 这个预处理的技巧巧妙的用了之前的处理结果.(大佬tql) 代码: #include <bits/st ...

  7. java用递归输出目录结构

    package com.janson.day20180827; import java.io.File; public class TestTreeStructureDirectory { publi ...

  8. python socket实现文件传输(防粘包)

    1.文件传输的要点: 采用iterator(迭代器对象)迭代读取,提高读取以及存取效率: 通过for line in file_handles逐行conn.send(): 2.socket粘包问题: ...

  9. 网络基础——TCP

    TCP和UDP协议特点 1.TCP 1>.传输控制协议 2>.可靠的.面向连接的协议 3>.传输效率低 2.UDP 1>.用户数据报协议 2>.不可靠的.无连接的服务 3 ...

  10. Entity SQL rules for Wrapped and Unwrapped Results

    Here are some rules to remember for Entity SQL queries: 1.Use SELECT VALUE when projecting more than ...