题目大意:给出一个由1到20组成的整数矩阵的每一行和每一列的和,构造这个矩阵。输出任意一个构造方案。

题目分析:将每一行视作一个点x,将每一列视作一个点y。对于矩阵中的每一个格子,都对应一个二元关系<x,y>,从x连一条有向弧到y,容量置为19。增加源点s和汇点t,对于每一个x,连一条从s到x的有向弧,容量置为对应的该行总和减去列数,对于每一个y,连一条从y到t的有向弧,容量置为对应的该列总和减去行数。对于这个寻找最大流,算法终止后,如果从s出发的每一条弧和到达t的每一条弧都是饱和的,那么每一个xi到yj的流量便是对应格子中的值减一;否则,无解。这道题,一定有解。  显然,这样建模是正确的。

代码如下:

  1. # include<iostream>
  2. # include<cstdio>
  3. # include<cmath>
  4. # include<string>
  5. # include<vector>
  6. # include<list>
  7. # include<set>
  8. # include<map>
  9. # include<queue>
  10. # include<cstring>
  11. # include<algorithm>
  12. using namespace std;
  13.  
  14. # define LL long long
  15. # define REP(i,s,n) for(int i=s;i<n;++i)
  16. # define CL(a,b) memset(a,b,sizeof(a))
  17. # define CLL(a,b,n) fill(a,a+n,b)
  18.  
  19. const double inf=1e30;
  20. const int INF=1<<30;
  21. const int N=1000;
  22.  
  23. struct Edge
  24. {
  25. int fr,to,cap,flow;
  26. Edge(int _fr,int _to,int _cap,int _flow):fr(_fr),to(_to),cap(_cap),flow(_flow){}
  27. };
  28. vector<Edge>edge;
  29. int id[50][50],r,c,a[25],b[25],f[50],p[50];
  30. vector<int>G[50];
  31.  
  32. void init()
  33. {
  34. a[0]=b[0]=0;
  35. REP(i,0,r+c+2) G[i].clear();
  36. edge.clear();
  37. }
  38.  
  39. void addEdge(int fr,int to,int cap)
  40. {
  41. edge.push_back(Edge(fr,to,cap,0));
  42. edge.push_back(Edge(to,fr,0,0));
  43. int m=edge.size();
  44. id[fr][to]=m-2;
  45. G[fr].push_back(m-2);
  46. G[to].push_back(m-1);
  47. }
  48.  
  49. void maxFlow(int s,int t)
  50. {
  51. while(1)
  52. {
  53. queue<int>q;
  54. CL(f,0);
  55. f[s]=INF;
  56. q.push(s);
  57. while(!q.empty()){
  58. int u=q.front();
  59. q.pop();
  60. REP(i,0,G[u].size()){
  61. Edge &e=edge[G[u][i]];
  62. if(!f[e.to]&&e.cap>e.flow){
  63. p[e.to]=G[u][i];
  64. f[e.to]=min(f[u],e.cap-e.flow);
  65. q.push(e.to);
  66. }
  67. }
  68. if(f[t]) break;
  69. }
  70. if(!f[t]) break;
  71. for(int u=t;u!=s;u=edge[p[u]].fr){
  72. edge[p[u]].flow+=f[t];
  73. edge[p[u]^1].flow-=f[t];
  74. }
  75. }
  76. }
  77.  
  78. int main()
  79. {
  80. int T,cas=0;
  81. scanf("%d",&T);
  82. while(T--)
  83. {
  84. scanf("%d%d",&r,&c);
  85. init();
  86. REP(i,1,r+1) scanf("%d",a+i);
  87. REP(i,1,c+1) scanf("%d",b+i);
  88. REP(i,1,r+1) addEdge(0,i,a[i]-a[i-1]-c);
  89. REP(i,1,r+1) REP(j,r+1,r+c+1) addEdge(i,j,19);
  90. REP(i,r+1,r+c+1) addEdge(i,r+c+1,b[i-r]-b[i-r-1]-r);
  91. maxFlow(0,r+c+1);
  92. printf("Matrix %d\n",++cas);
  93. REP(i,1,r+1) REP(j,1,c+1) printf("%d%c",edge[id[i][j+r]].flow+1,(j==c)?'\n':' ');
  94. if(T) printf("\n");
  95. }
  96.   return 0;
  97. }

  

UVA-11082 Matrix Decompressing (网络流建模)的更多相关文章

  1. UVa 11082 Matrix Decompressing - 网络流

    开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...

  2. UVA 11082 矩阵解压(网络流建模)

    矩阵解压 紫书P374 建模真的是挺难的,如果直接给我这题,我是想不到用网络流的,所以还应多做网路流建模,学会如何转化成网络流 还有,现在用的EK算法是比较慢的,还应去看看Dnic和ISAP,并且理解 ...

  3. UVa 11082 Matrix Decompressing(最大流)

    不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...

  4. UVA - 11082 Matrix Decompressing

    2. B - Matrix Decompressing 题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和. 题目已知R,C和数 ...

  5. [题解]UVa 11082 Matrix Decompressing

    开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...

  6. UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)

    题意: 知道矩阵的前i行之和,和前j列之和(任意i和j都可以).求这个矩阵.每个格子中的元素必须在1~20之间.矩阵大小上限20*20. 思路: 这么也想不到用网络流解决,这个模型很不错.假设这个矩阵 ...

  7. UVa 11082 - Matrix Decompressing(最大流)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. UVA - 11082 Matrix Decompressing (最大流,技巧)

    很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了. 建图的时候注意分配好编号,解从残留网络中的边找 ...

  9. uva 11082 Matrix Decompressing 【 最大流 】

    只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~ 建图好神奇~~ 最开始不懂---后来看了一下这篇-- http://www.cnblogs.com/AOQNRMGYXLMV/p/42807 ...

  10. UVA - 11082 Matrix Decompressing(最大流+行列模型)

    题目大意:给出一个R行C列的矩阵,如今给出他的前1-R行和 && 前1-C列和,问这个矩阵原来是如何的,要求每一个元素大小在1-20之间 解题思路:将每一行连接到超级源点,容量为该行的 ...

随机推荐

  1. C++和C#的思考

    从2011年从业至今已经写了7年C++了,而C#.go语言虽然早有涉猎,但直到最近才开始思考语言的发展和工程之间的关系. C++ 更容易写出高内聚代码使用指针做原地内存操作直接堆栈控制,减少内存分配, ...

  2. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

  3. Spring源码解析(二)BeanDefinition的Resource定位

    IOC容器的初始化过程主要包括BeanDefinition的Resource定位.载入和注册.在实际项目中我们基本上操作的都是ApplicationContex的实现,我们比较熟悉的ClassPath ...

  4. mysql中的多行查询结果合并成一个(转)

    SELECT GROUP_CONCAT(md.data1) FROM DATA md,contacts cc WHERE md.conskey=cc.id AND md.mimetype_id= 5 ...

  5. mysql根据经纬度获取附近的商家

    create table geo( geo_id INT NOT NULL AUTO_INCREMENT, lng float NOT NULL, lat float NOT NULL, name ) ...

  6. PAT 1105 Spiral Matrix[模拟][螺旋矩阵][难]

    1105 Spiral Matrix(25 分) This time your job is to fill a sequence of N positive integers into a spir ...

  7. chrome 调试 ios的 H5 页面

    原文地址http://www.cnblogs.com/kelsen/p/6402477.html 本文重点讨论如何在 Windows 系统中通过chrome 浏览器调试运行在 iPhone Safar ...

  8. Codeforces Round #532 (Div. 2) Solution

    A. Roman and Browser 签到. #include <bits/stdc++.h> using namespace std; ]; int get(int b) { ]; ...

  9. ACM-ICPC 2018 徐州赛区网络预赛 Solution

    A. Hard to prepare 题意:有n个客人做成一圈,有$2^k$种面具,对于每种面具有一种面具不能使相邻的两个人戴,共有多少种做法. 思路: 把题意转化成相邻的人不能带同种面具.总数为$( ...

  10. Linux 基础 —— Linux 进程的管理与监控

    这篇文章主要讲 Linux 中进程的概念和进程的管理工具.原文:http://liaoph.com/inux-process-management/ 进程的概念 什么是进程 进程(Process)是计 ...