链接:

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

题意:

对于一个R行C列的正整数矩阵(1≤R,C≤20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和。
已知R,C和数组A和B,找一个满足条件的矩阵。矩阵中的元素必须是1~20之间的正整数。输入保证有解。

分析:

首先根据Ai和Bi计算出第i行的元素之和Ai'和第i列的元素之和Bi'。
如果把矩阵里的每个数都减1,则每个Ai'会减少C,而每个Bi'会减少R。
这样一来,每个元素的范围变成了0~19,它的好处很快就能看到。
建立一个二分图,每行对应一个X结点,每列对应一个Y结点,然后增加源点s和汇点t。
对于每个结点Xi,从s到Xi连一条弧,容量为Ai'-C;从Yi到t连一条弧,容量为Bi'-R。
而对于每对结点(Xi,Yj),从Xi向Yj连一条弧,容量为19。
接下来求s-t的最大流,如果所有s出发和到达t的边都满载,说明问题有解,
结点Xi->Yj的流量就是格子(i,j)减1之后的值。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. #include <vector>
  5. using namespace std;
  6.  
  7. /// 结点下标从0开始,注意maxn
  8. struct Dinic {
  9. static const int maxn = + ;
  10. static const int INF = 0x3f3f3f3f;
  11. struct Edge {
  12. int from, to, cap, flow;
  13. };
  14.  
  15. int n, m, s, t; // 结点数,边数(包括反向弧),源点编号和汇点编号
  16. vector<Edge> edges; // 边表。edges[e]和edges[e^1]互为反向弧
  17. vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
  18. bool vis[maxn]; // BFS使用
  19. int d[maxn]; // 从起点到i的距离
  20. int cur[maxn]; // 当前弧下标
  21.  
  22. void init(int n) {
  23. this->n = n;
  24. edges.clear();
  25. for(int i = ; i < n; i++) G[i].clear();
  26. }
  27. void AddEdge(int from, int to, int cap) {
  28. edges.push_back((Edge){from, to, cap, });
  29. edges.push_back((Edge){to, from, , });
  30. m = edges.size();
  31. G[from].push_back(m-);
  32. G[to].push_back(m-);
  33. }
  34. bool BFS() {
  35. memset(vis, , sizeof(vis));
  36. queue<int> Q;
  37. Q.push(s);
  38. vis[s] = ;
  39. d[s] = ;
  40. while(!Q.empty()) {
  41. int x = Q.front(); Q.pop();
  42. for(int i = ; i < G[x].size(); i++) {
  43. Edge& e = edges[G[x][i]];
  44. if(!vis[e.to] && e.cap > e.flow) { // 只考虑残量网络中的弧
  45. vis[e.to] = ;
  46. d[e.to] = d[x] + ;
  47. Q.push(e.to);
  48. }
  49. }
  50. }
  51. return vis[t];
  52. }
  53. int DFS(int x, int a) {
  54. if(x == t || a == ) return a;
  55. int flow = , f;
  56. for(int& i = cur[x]; i < G[x].size(); i++) { // 从上次考虑的弧
  57. Edge& e = edges[G[x][i]];
  58. if(d[x]+ == d[e.to] && (f=DFS(e.to, min(a, e.cap-e.flow))) > ) {
  59. e.flow += f;
  60. edges[G[x][i]^].flow -= f;
  61. flow += f;
  62. a -= f;
  63. if(a == ) break;
  64. }
  65. }
  66. return flow;
  67. }
  68. int Maxflow(int s, int t) {
  69. this->s = s; this->t = t;
  70. int flow = ;
  71. while(BFS()) {
  72. memset(cur, , sizeof(cur));
  73. flow += DFS(s, INF);
  74. }
  75. return flow;
  76. }
  77. vector<int> Mincut() { // 在Maxflow之后调用
  78. vector<int> ans;
  79. for(int i = ; i < edges.size(); i++) {
  80. Edge& e = edges[i];
  81. if(vis[e.from] && !vis[e.to] && e.cap > ) ans.push_back(i);
  82. }
  83. return ans;
  84. }
  85. };
  86.  
  87. const int UP = + ;
  88. int id[UP][UP];
  89. Dinic dc;
  90.  
  91. int main() {
  92. int T, R, C;
  93. scanf("%d", &T);
  94. for(int cases = ; cases <= T; cases++) {
  95. scanf("%d%d", &R, &C);
  96. dc.init(R+C+);
  97. int start = R+C, finish = R+C+, last = ;
  98. for(int v, i = ; i < R; i++) {
  99. scanf("%d", &v);
  100. dc.AddEdge(start, i, v - last - C);
  101. last = v;
  102. }
  103. last = ;
  104. for(int v, i = ; i < C; i++) {
  105. scanf("%d", &v);
  106. dc.AddEdge(R+i, finish, v - last - R);
  107. last = v;
  108. }
  109. for(int r = ; r < R; r++) {
  110. for(int c = ; c < C; c++) {
  111. dc.AddEdge(r, R+c, );
  112. id[r][c] = dc.edges.size() - ;
  113. }
  114. }
  115.  
  116. dc.Maxflow(start, finish);
  117. printf("Matrix %d\n", cases);
  118. for(int r = ; r < R; r++) {
  119. for(int c = ; c < C; c++) {
  120. printf("%d ", dc.edges[id[r][c]].flow + );
  121. }
  122. printf("\n");
  123. }
  124. printf("\n");
  125. }
  126. return ;
  127. }

UVa 11082 - Matrix Decompressing(最大流)的更多相关文章

  1. UVa 11082 Matrix Decompressing(最大流)

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

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

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

  3. UVA - 11082 Matrix Decompressing

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

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

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

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

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

  6. uva 11082 Matrix Decompressing 【 最大流 】

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

  7. [题解]UVa 11082 Matrix Decompressing

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

  8. UVa 11082 Matrix Decompressing - 网络流

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

  9. UVA11082 Matrix Decompressing 最大流建模解矩阵,经典

    /** 题目:UVA11082 Matrix Decompressing 链接:https://vjudge.net/problem/UVA-11082 题意:lrj入门经典P374 已知一个矩阵的行 ...

随机推荐

  1. React+Three.js——PerspectiveCamera透视相机camera参数以及属性值探索

    因项目问题,对webgl进行了探索,当进行到3d相机时,对camera的up,position属性有部分难以理解的地方,因此做下了记录. 代码如下: import React, {Component} ...

  2. java--多线程之后台线程

    public class ThreadDaemon { /** * @param args * 后台线程在主进程结束后,也会退出 */ public static void main(String[] ...

  3. 项目管理系列--谷歌的code review

    Google 开源项目风格指南 (中文版) 在线文档托管在 ReadTheDocs : 在线阅读最新版本 中文风格指南 GitHub 托管地址:zh-google-styleguide 声明. 本项目 ...

  4. spring mvc 基本配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. 如何查找消耗资源较大的SQL

    对于优化来讲,查找消耗资源较大的SQL至关重要,下面介绍几个之前用到的SQL. 1.从V$SQLAREA中查询最占用资源的查询. select b.username username,a.disk_r ...

  6. ios audio不能自动播放

    今天做了一个简单的落地页项目,就是类似于手机微信上经常看到的滑动效果.因为公司要求需要自己开发,所以我就用swiper+swiper.animate开发,开发速度很快,只不过最后音乐哪里出现了一点小b ...

  7. php strpos返回字符串首次出现的位置

    (PHP 4, PHP 5, PHP 7) strpos — 查找字符串首次出现的位置 说明 mixed strpos ( string $haystack , mixed $needle [, in ...

  8. c语言printf实现同一位置打印输出

    控制台同一位置打印输出,例如:进度1%->100%在同一位置显示.刚学习c语言的时候一直想做起来,可惜查询好多资料不行.时隔6年多,空闲之余又想起这个问题,便决定一试,虽然c语言已经几乎忘光了, ...

  9. Node.js开发——MongoDB与Mongoose

    为了保存网站的用户数据和业务数据,通常需要一个数据库.MongoDB和Node.js特别般配,因为MongoDB是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储的,增删改 ...

  10. react-native一些好的组件

    一.移动端路由 react-navigator 二.移动端本地储存 react-native-storage(https://github.com/sunnylqm/react-native-stor ...