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

UVa 11082 (网络流建模) Matrix Decompressing

时间:2015-02-09 00:39:43      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:

网络流不难写,难的建一个能解决问题的模型。。

即使我知道这是网络流专题的题目,也绝不会能想出这种解法,=_=||

题意:

给出一个矩阵的 前i行和 以及 前i列和,然后找到一个满足要求的矩阵,而且每个元素在1~20之间。

分析:

先求出每行的元素和A‘i    每列的元素和B‘i

紫书上说建一个二分图,每行是一个X节点,每列代表一个Y节点。

因为流量最小是0,而题中说元素大小在1~20之间,所以我们先将每个元素都减一。

这样每行的元素和就变成了A‘i-C,每列之和变为B‘i-R

XY之间每条边的容量为19

源点到X中每个点的容量为A‘i-C,Y中的每个点到汇点的容量为B‘i-R。当所有从源点出发和在汇点结束的边满载时有解。

 

“为什么这样做是对的呢?请读者思考。”

好吧,那我就思考。Xi->Yj这条边就对应矩阵中第i行第j列元素的值,而且所有从X出发的边,汇聚到Yj的总流量就是第j列的和。

反过来,从Xi出发的总流量就是第i行的和,分流到各个Y中。

技术分享
  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 const int maxn = 50 + 5;
  6 const int INF = 1000000000;
  7 
  8 struct Edge
  9 {
 10     int from, to, cap, flow;
 11     Edge(int u=0, int v=0, int c=0, int f=0): from(u), to(v), cap(c), flow(f) {}
 12 };
 13 
 14 struct EdmondsKarp
 15 {
 16     int n, m;
 17     vector<Edge> edges;
 18     vector<int> G[maxn];
 19     int a[maxn];
 20     int p[maxn];
 21 
 22     void Init(int n)
 23     {
 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     {
 30         edges.push_back(Edge(from, to, cap, 0));
 31         edges.push_back(Edge(to, from, 0, 0));
 32         m = edges.size();
 33         G[from].push_back(m-2);
 34         G[to].push_back(m-1);
 35     }
 36 
 37     int MaxFlow(int s, int t)
 38     {
 39         int flow = 0;
 40         for(;;)
 41         {
 42             memset(a, 0, sizeof(a));
 43             queue<int> Q;
 44             Q.push(s);
 45             a[s] = INF;
 46             while(!Q.empty())
 47             {
 48                 int x = Q.front(); Q.pop();
 49                 for(int i = 0; i < G[x].size(); ++i)
 50                 {
 51                     Edge& e = edges[G[x][i]];
 52                     if(!a[e.to] && e.cap > e.flow)
 53                     {
 54                         a[e.to] = min(a[x], e.cap - e.flow);
 55                         p[e.to] = G[x][i];
 56                         Q.push(e.to);
 57                     }
 58                 }
 59                 if(a[t]) break;
 60             }
 61             if(!a[t]) break;
 62             for(int u = t; u != s; u = edges[p[u]].from)
 63             {
 64                 edges[p[u]].flow += a[t];
 65                 edges[p[u]^1].flow -= a[t];
 66             }
 67             flow += a[t];
 68         }
 69         return flow;
 70     }
 71 };
 72 
 73 EdmondsKarp g;
 74 int ind[maxn][maxn];//ind[i][j]记录第i行第j列对应的边的编号
 75 
 76 int main()
 77 {
 78     //freopen("in.txt", "r", stdin);
 79 
 80     int T, R, C;
 81     scanf("%d", &T);
 82     for(int kase = 1; kase <= T; ++kase)
 83     {
 84         scanf("%d%d", &R, &C);
 85         g.Init(R+C+2);
 86         int cur, last = 0;
 87         for(int i = 1; i <= R; ++i)
 88         {//第i行的节点标号为i,源点标号为0
 89             scanf("%d", &cur);
 90             g.AddEdge(0, i, cur - last - C);
 91             last = cur;
 92         }
 93         last = 0;
 94         for(int i = 1; i <= C; ++i)
 95         {//第i列的标号为R+i,汇点标号为R+C+1
 96             scanf("%d", &cur);
 97             g.AddEdge(R+i, R+C+1, cur - last - R);
 98             last = cur;
 99         }
100         for(int i = 1; i <= R; ++i)
101             for(int j = 1; j <= C; ++j)
102             {
103                 g.AddEdge(i, j+R, 19);
104                 ind[i][j] = g.edges.size() - 2;//因为AddEdge中还有一条反向边,所以是-2
105             }
106         g.MaxFlow(0, R+C+1);
107 
108         printf("Matrix %d\n", kase);
109         for(int i = 1; i <= R; ++i)
110         {
111             printf("%d", g.edges[ind[i][1]].flow + 1);
112             for(int j = 2; j <= C; ++j)
113                 printf(" %d", g.edges[ind[i][j]].flow + 1);
114             printf("\n");
115         }
116         printf("\n");
117     }
118 
119     return 0;
120 }
代码君

 

UVa 11082 (网络流建模) Matrix Decompressing

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4280727.html

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