码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 11082 Matrix Decompressing (网络流)

时间:2016-08-24 00:56:40      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

链接:http://acm.hust.edu.cn/vjudge/problem/36866
题意:
对于一个R行C列的正整数矩阵(1≤R,C≤20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和。已知R,C和数组A和B,找一个满足条件的矩阵。矩阵中的元素必须是1~20之间的正整数。输入保证有解。
分析:
这道题主要还是考查建模能力。如何把一个矩阵模型转化成网络流模型是关键之处。首先注意到矩阵任意行或列的元素之和是不变的(设第i行元素之和为Ai′,第i列元素之和为Bi′),因此想到把矩阵的每行和每列都看成是一个结点,然后增设一个源点s和一个汇点t,并将矩阵中的每个元素减1,
然后从源点s向各个行结点Xi连一条弧,那么容量为Ai′-C(由于先前使每个元素减去1每行总的减去C,使得s到Xi的容量下界为0上界为Ai′-C),从各个列结点Yi向t连一条弧,容量为Bi′-R(同理),对于每个矩阵元素(Xi,Yj),从结点Xi向Yj连一条弧,容量为19,接下来就是求s-t的最大流,有解的条件是s出发和到达t都要满载,原因是每行和每列的元素之和是不变的,格子(i,j)的值就是结点Xi->Yj的流量加上1(先前每个元素都减去了1)。
  1 #include <cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<vector>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 const int maxn = 40 + 5;
  9 const int INF = 1000000000;
 10 
 11 struct Edge {
 12     int from, to, cap, flow;
 13     Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
 14 };
 15 
 16 struct EdmondsKarp {
 17     int n, m;
 18     vector<Edge> edges;
 19     vector<int> G[maxn];
 20     int a[maxn];
 21     int p[maxn];
 22 
 23     void init(int n) {
 24         for (int i = 0; i < n; i++) G[i].clear();
 25         edges.clear();
 26     }
 27 
 28     void AddEdge(int from, int to, int cap) {
 29         edges.push_back(Edge(from, to, cap, 0));
 30         edges.push_back(Edge(to, from, 0, 0));
 31         m = edges.size();
 32         G[from].push_back(m - 2);
 33         G[to].push_back(m - 1);
 34     }
 35 
 36     int Maxflow(int s, int t) {
 37         int flow = 0;
 38         for (;;) {
 39             memset(a, 0, sizeof(a));
 40             queue<int> Q;
 41             Q.push(s);
 42             a[s] = INF;
 43             while (!Q.empty()) {
 44                 int x = Q.front(); Q.pop();
 45                 for (int i = 0; i < G[x].size(); i++) {
 46                     Edge& e = edges[G[x][i]];
 47                     if (!a[e.to] && e.cap > e.flow) {
 48                         p[e.to] = G[x][i];
 49                         a[e.to] = min(a[x], e.cap - e.flow);
 50                         Q.push(e.to);
 51                     }
 52                 }
 53                 if (a[t]) break;
 54             }
 55             if (!a[t]) break;
 56             for (int u = t; u != s; u = edges[p[u]].from) {
 57                 edges[p[u]].flow += a[t];
 58                 edges[p[u] ^ 1].flow -= a[t];
 59             }
 60             flow += a[t];
 61         }
 62         return flow;
 63     }
 64 };
 65 
 66 EdmondsKarp g;
 67 int idex[maxn][maxn];
 68 
 69 int main() {
 70     int T;
 71     scanf("%d", &T);
 72     for (int kase = 1; kase <= T; kase++) {
 73         int r, c;
 74         scanf("%d%d", &r, &c);
 75         g.init(r + c + 2);
 76         int v, last = 0;
 77         for (int i = 1; i <= r; i++) {
 78             scanf("%d", &v);
 79             g.AddEdge(0, i, v - last - c);
 80             last = v;
 81         }
 82         last = 0;
 83         for (int i = 1; i <= c; i++) {
 84             scanf("%d", &v);
 85             g.AddEdge(r + i, r + c + 1, v - last - r);
 86             last = v;
 87         }
 88         for (int i = 1; i <= r; i++)
 89             for (int j = 1; j <= c; j++) {
 90                 g.AddEdge(i, r + j, 19);
 91                 idex[i][j] = g.edges.size() - 2;
 92             }
 93         g.Maxflow(0, r + c + 1);
 94         printf("Matrix %d\n", kase);
 95         for (int i = 1; i <= r; i++) {
 96             for (int j = 1; j <= c; j++)
 97                 printf("%d ", g.edges[idex[i][j]].flow + 1);
 98             putchar(\n);
 99         }
100         putchar(\n);
101     }
102     return 0;
103 }

 




UVa 11082 Matrix Decompressing (网络流)

标签:

原文地址:http://www.cnblogs.com/XieWeida/p/5801352.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!