题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975

Problem Description
Dragon is studying math. One day, he drew a table with several rows and columns, randomly wrote numbers on each elements of the table. Then he counted the sum of each row and column. Since he thought the map will be useless after he got the sums, he destroyed
the table after that.



However Dragon's mom came back and found what he had done. She would give dragon a feast if Dragon could reconstruct the table, otherwise keep Dragon hungry. Dragon is so young and so simple so that the original numbers in the table are one-digit number (e.g.
0-9).



Could you help Dragon to do that?
 
Input
The first line of input contains only one integer, T(<=30), the number of test cases. Following T blocks, each block describes one test case.



There are three lines for each block. The first line contains two integers N(<=500) and M(<=500), showing the number of rows and columns.



The second line contains N integer show the sum of each row.



The third line contains M integer show the sum of each column.
 
Output
Each output should occupy one line. Each line should start with "Case #i: ", with i implying the case number. For each case, if we cannot get the original table, just output: "So naive!", else if we can reconstruct the table by more than one ways, you should
output one line contains only: "So young!", otherwise (only one way to reconstruct the table) you should output: "So simple!".
 
Sample Input
  1. 3
  2. 1 1
  3. 5
  4. 5
  5. 2 2
  6. 0 10
  7. 0 10
  8. 2 2
  9. 2 2
  10. 2 2
 
Sample Output
  1. Case #1: So simple!
  2. Case #2: So naive!
  3. Case #3: So young!
 
Source

题意:

给出每行每列的和,问是否存在这种表格;每一个小格放的数字仅仅能是0--9。

官方题解:http://blog.sina.com.cn/s/blog_6bddecdc0102v01l.html

代码例如以下:(套用别人HDU4888的模板)

  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<string.h>
  4. #include<algorithm>
  5. #include<math.h>
  6. #include<queue>
  7. using namespace std;
  8. #define ll __int64
  9. #define eps 1e-8
  10. const ll Mod=(1e9+7);
  11. const int maxn = 510;
  12. const int maxm = 50100;
  13.  
  14. int n,m,k;
  15. int r[maxn],c[maxn];
  16. int ma[maxn][maxn];
  17.  
  18. const int maxnode = 10000 + 5;
  19. const int maxedge = 2*1000000 + 5;
  20. const int oo = 1000000000;
  21. int node, src, dest, nedge;
  22. int head[maxnode], point[maxedge], next1[maxedge], flow[maxedge], capa[maxedge];//point[x]==y表示第x条边连接y,head,next为邻接表,flow[x]表示x边的动态值,capa[x]表示x边的初始值
  23. int dist[maxnode], Q[maxnode], work[maxnode];//dist[i]表示i点的等级
  24. void init(int _node, int _src, int _dest) //初始化,node表示点的个数,src表示起点,dest表示终点
  25. {
  26. node = _node;
  27. src = _src;
  28. dest = _dest;
  29. for (int i = 0; i < node; i++) head[i] = -1;
  30. nedge = 0;
  31. }
  32. void addedge(int u, int v, int c1, int c2) //添加一条u到v流量为c1,v到u流量为c2的两条边
  33. {
  34. point[nedge] = v, capa[nedge] = c1, flow[nedge] = 0, next1[nedge] = head[u], head[u] = (nedge++);
  35. point[nedge] = u, capa[nedge] = c2, flow[nedge] = 0, next1[nedge] = head[v], head[v] = (nedge++);
  36. }
  37. bool dinic_bfs()
  38. {
  39. memset(dist, 255, sizeof (dist));
  40. dist[src] = 0;
  41. int sizeQ = 0;
  42. Q[sizeQ++] = src;
  43. for (int cl = 0; cl < sizeQ; cl++)
  44. for (int k = Q[cl], i = head[k]; i >= 0; i = next1[i])
  45. if (flow[i] < capa[i] && dist[point[i]] < 0)
  46. {
  47. dist[point[i]] = dist[k] + 1;
  48. Q[sizeQ++] = point[i];
  49. }
  50. return dist[dest] >= 0;
  51. }
  52. int dinic_dfs(int x, int exp)
  53. {
  54. if (x == dest) return exp;
  55. for (int &i = work[x]; i >= 0; i = next1[i])
  56. {
  57. int v = point[i], tmp;
  58. if (flow[i] < capa[i] && dist[v] == dist[x] + 1 && (tmp = dinic_dfs(v, min(exp, capa[i] - flow[i]))) > 0)
  59. {
  60. flow[i] += tmp;
  61. flow[i^1] -= tmp;
  62. return tmp;
  63. }
  64. }
  65. return 0;
  66. }
  67. int dinic_flow()
  68. {
  69. int result = 0;
  70. while (dinic_bfs())
  71. {
  72. for (int i = 0; i < node; i++) work[i] = head[i];
  73. while (1)
  74. {
  75. int delta = dinic_dfs(src, oo);
  76. if (delta == 0) break;
  77. result += delta;
  78. }
  79. }
  80. return result;
  81. }
  82. //建图前,执行一遍init();
  83. //加边时,执行addedge(a,b,c,0),表示点a到b流量为c的边建成(注意点序号要从0開始)
  84. //求解最大流执行dinic_flow(),返回值即为答案
  85.  
  86. bool judge(int sumrow)
  87. {
  88. int flow = 1,cost = 0;
  89. for(int i = 1; i <= n; i++)
  90. for(int j = n+1; j <= n+m; j ++)
  91. addedge(i,j,k,0);
  92. flow=dinic_flow();
  93. if(flow != sumrow)
  94. return false;
  95. return true;
  96. }
  97. int main()
  98. {
  99. //k为能填原图能填的数字的最大值
  100. int t;
  101. int cas = 0;
  102. scanf("%d",&t);
  103. while(t--)
  104. {
  105. scanf("%d%d",&n,&m);
  106. k = 9;//最多能填9
  107. init(n+m+2,0,n+m+1);
  108. int flag = 0;
  109. int sumrow = 0,colrow = 0;
  110. for(int i = 1; i <= n; i++)
  111. {
  112. scanf("%d",&r[i]);
  113. addedge(0,i,r[i],0);
  114. sumrow += r[i];
  115. if(r[i]<0 || r[i]>m*k)
  116. flag = 1;
  117. }
  118. for(int j = 1; j <= m; j ++)
  119. {
  120. scanf("%d",&c[j]);
  121. addedge(j+n,n+m+1,c[j],0);
  122. colrow += c[j];
  123. if(c[j]<0 || c[j]>n*k)
  124. flag = 1;
  125. }
  126. if(sumrow != colrow)
  127. {
  128. printf("Case #%d: So naive!\n",++cas);
  129. continue;
  130. }
  131. if(!judge(sumrow))
  132. flag = 1;
  133. if(flag == 1)
  134. {
  135. printf("Case #%d: So naive!\n",++cas);
  136. continue;
  137. }
  138. memset(ma,-1,sizeof(ma));
  139. int i,j;
  140. for(i=1; i<=n; i++)
  141. if(r[i]==0)
  142. for(j=1; j<=m; j++)
  143. ma[i][j]=0;
  144. for(j=1; j<=m; j++)
  145. if(c[j]==0)
  146. for(i=1; i<=n; i++)
  147. ma[i][j]=0;
  148. int tt=2;
  149. int sum,num,temp;
  150. while(tt--)
  151. {
  152. for(i=1; i<=n; i++)
  153. {
  154. if(r[i]==0)
  155. {
  156. for(j=1; j<=m; j++)
  157. if(ma[i][j]==-1)
  158. ma[i][j]=0;
  159. continue;
  160. }
  161. sum=0;
  162. num=0;
  163. for(j=1; j<=m; j++)
  164. {
  165. if(ma[i][j]==-1)
  166. {
  167. num++;
  168. temp=j;
  169. sum+=min(k,c[j]);
  170. }
  171. }
  172. if(num==1)
  173. {
  174. ma[i][temp]=r[i];
  175. r[i]-=ma[i][temp];
  176. c[temp]-=ma[i][temp];
  177. continue;
  178. }
  179. else if(sum==r[i])
  180. {
  181. for(j=1; j<=m; j++)
  182. {
  183. if(ma[i][j]==-1)
  184. {
  185. ma[i][j]=min(k,c[j]);
  186. r[i]-=ma[i][j];
  187. c[j]-=ma[i][j];
  188. }
  189. }
  190. }
  191. }
  192. for(j=1; j<=m; j++)
  193. {
  194. if(c[j]==0)
  195. {
  196. for(i=1; i<=n; i++)
  197. if(ma[i][j]==-1)
  198. ma[i][j]=0;
  199. continue;
  200. }
  201. sum=0;
  202. num=0;
  203. for(i=1; i<=n; i++)
  204. {
  205. if(ma[i][j]==-1)
  206. {
  207. num++;
  208. temp=i;
  209. sum+=min(k,r[i]);
  210. }
  211. }
  212. if(num==1)
  213. {
  214. ma[temp][j]=c[j];
  215. r[temp]-=ma[temp][j];
  216. c[j]-=ma[temp][j];
  217. continue;
  218. }
  219. else if(sum==c[j])
  220. {
  221. for(i=1; i<=n; i++)
  222. {
  223. if(ma[i][j]==-1)
  224. {
  225. ma[i][j]=min(k,r[i]);
  226. r[i]-=ma[i][j];
  227. c[j]-=ma[i][j];
  228. }
  229. }
  230. }
  231. }
  232. }
  233. flag=0;
  234. for(i=1; i<=n; i++)
  235. if(r[i]!=0)
  236. {
  237. flag=1;
  238. break;
  239. }
  240. for(j=1; j<=m; j++)
  241. if(c[j]!=0)
  242. {
  243. flag=1;
  244. break;
  245. }
  246. if(flag==1)
  247. printf("Case #%d: So young!\n",++cas);
  248. else
  249. {
  250. printf("Case #%d: So simple!\n",++cas);
  251. /* for(i=1; i<=n; i++)
  252. {
  253. for(j=1; j<m; j++)
  254. printf("%d ",ma[i][j]);
  255. printf("%d\n",ma[i][m]);
  256. }*/
  257. }
  258. }
  259. return 0;
  260. }

hdu 4975 A simple Gaussian elimination problem.(网络流,推断矩阵是否存在)的更多相关文章

  1. HDU 4975 A simple Gaussian elimination problem.

    A simple Gaussian elimination problem. Time Limit: 1000ms Memory Limit: 65536KB This problem will be ...

  2. hdu - 4975 - A simple Gaussian elimination problem.(最大流量)

    意甲冠军:要在N好M行和列以及列的数字矩阵和,每个元件的尺寸不超过9,询问是否有这样的矩阵,是独一无二的N(1 ≤ N ≤ 500) , M(1 ≤ M ≤ 500). 主题链接:http://acm ...

  3. hdu 4975 A simple Gaussian elimination problem 最大流+找环

    原题链接 http://acm.hdu.edu.cn/showproblem.php?pid=4975 这是一道很裸的最大流,将每个点(i,j)看作是从Ri向Cj的一条容量为9的边,从源点除法连接每个 ...

  4. HDOJ 4975 A simple Gaussian elimination problem.

    和HDOJ4888是一样的问题,最大流推断多解 1.把ISAP卡的根本出不来结果,仅仅能把全为0或者全为满流的给特判掉...... 2.在残量网络中找大于2的圈要用一种类似tarjian的方法从汇点開 ...

  5. A simple Gaussian elimination problem.(hdu4975)网络流+最大流

    A simple Gaussian elimination problem. Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65 ...

  6. hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)

    这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...

  7. A simple Gaussian elimination problem.

    hdu4975:http://acm.hdu.edu.cn/showproblem.php?pid=4975 题意:给你一个n*m的矩阵,矩阵中的元素都是0--9,现在给你这个矩阵的每一行和每一列的和 ...

  8. hdu4975 A simple Gaussian elimination problem.(最大流+判环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 题意:和hdu4888基本一样( http://www.cnblogs.com/a-clown/ ...

  9. hdu 4972 A simple dynamic programming problem(高效)

    pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...

随机推荐

  1. Objective-C浅拷贝和深拷贝

    浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间 如: char* str = (char*)malloc(100);char* str2 = str; 浅拷贝只是对对象的简单拷贝 ...

  2. Gimp制作圆角透明图片

    用蒙版制作圆角透明图片,步骤如下: 1,用Gimp(2.8版本)打开图片 2,在图层窗口右键当前图层创建蒙版 3,选择蒙版类型黑色(全透明) 4,结果如下 5,用圆角矩形选择工具选择图片,设置圆角半径 ...

  3. C++ 经常使用类 string类

    ===6.3.2使用string对象=== string word="I love China" *链接字符串* string description=adjective  + & ...

  4. 在js中获取query string 以及重写URL的函数

    函数用途:如标题.1. 从URL中解析出參数,2.重写URL中的參数值 例如以下代码所看到的.包括了測试.能够直接copy到浏览器中,输入測试地址:localhost:xxx?a=1&b=2& ...

  5. 在一个数组中是否存在两个数A、B的和为M

    #include <iostream>#include <algorithm>//#include <vector>using namespace std; int ...

  6. resolve "Undefined attribute name" warning for Angular "ng-" attributes in HTML files

    由于这些attributes引起的warning数量较多, 影响直观查找其他warning. 因此选择将这类warning忽视掉: Project Property -> Validation ...

  7. VS2010 .net4.0 登录QQ 获取QQ空间日志 右键选中直接打开日志 免积分 源码下载

    代码有一部分是原来写的  最近翻代码 看到了  就改了一下 CSDN上传源码 上传了几次都没 成功 郁闷   不知道怎么回事 上传不了 想要的留 邮箱 或加群77877965 下载地址在下面 演示地址 ...

  8. OSX/iOS 播放系统声音

    方法1: 系统会自带了些声音,有时候一些操作用必要自己播放一下声音提醒一下,用bash的直接say something就ok了,写代码的时候呢?原来很简单的,一句: [[NSSound soundNa ...

  9. 405 HTTP method GET is not supported by this URL

    孙鑫java web开发详解P285里面提交Get网站弹出提示405 HTTP method GET is not supported by this URL 原因父类doGet()方法未覆盖. 应写 ...

  10. (IOS)签名Demo

    思路是将每一次按下屏幕的touch move时的点存到一个数组里,即一个数组相当于一个笔画:再将该代表笔画的数组保存到一个大数组中,每组每次touch的移动都历遍大数组和笔画数组,将点于点之间连接起来 ...