UVA11082 Matrix Decompressing 最大流建模解矩阵,经典
Posted 天道酬勤007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA11082 Matrix Decompressing 最大流建模解矩阵,经典相关的知识,希望对你有一定的参考价值。
/** 题目:UVA11082 Matrix Decompressing 链接:https://vjudge.net/problem/UVA-11082 题意:lrj入门经典P374 已知一个矩阵的行数为r,列数为c,前i行的和ai(1<=i<=r),前j列的和bj(1<=j<=c)。 ai,bj都在[1,20]内。求出这个矩阵。 思路:通过前i行的和以及前j列的和,获得每一行的和以及每一列的和。 把每一行看做一个节点,每一列看做一个节点。 建立一个源点到达每一行。 建立一个汇点,每一列到达汇点。 每一行到达每一列。 由于数据范围是[1,20]。流可以说0.所以为了方便处理,所有容量-1.最后结果+1. 那么源点到第i行的容量为r[i]-列数。(每一行有列数个数) 第j列到汇点的容量为c[j]-行数。 第i行到第j列的容量都为19。(20-1) 每一行都经过每一列组成。所以这样建立连接。 如果源点到每一个行节点都是满载。 每一个列节点到汇点都是满载。 那么有解。 解为: 第i行第j列的元素为第i行的节点到第j列的节点的流+1。 */ #include<iostream> #include<cstring> #include<vector> #include<map> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int INF = 0x3f3f3f3f; typedef long long LL; const int N = 110; int r[N], c[N]; struct Edge{ int from, to, cap, flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} }; struct EdmondsKarp { int n, m; vector<Edge> edges; vector<int> G[N]; int p[N]; int a[N]; int ans[N][N]; void init(int n) { for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap){ edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } int Maxflow(int s,int t) { int flow = 0; for(;;){ memset(a, 0, sizeof a); queue<int>Q; Q.push(s); a[s] = INF; while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); i++){ Edge& e = edges[G[x][i]]; if(!a[e.to]&&e.cap>e.flow){ p[e.to] = G[x][i]; a[e.to] = min(a[x],e.cap-e.flow); Q.push(e.to); } } if(a[t]) break; } if(!a[t]) break; for(int u = t; u != s; u = edges[p[u]].from){ edges[p[u]].flow += a[t]; edges[p[u]^1].flow -= a[t]; } flow += a[t]; } return flow; } void getMatrix() { int r = 0, c = 0; for(int i = 2*(n+m); i < edges.size(); i+=2){ if(c==m) { r++, c = 0; } ans[r][c] = edges[i].flow; c++; } for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if(j==m-1) printf("%d\n",ans[i][j]+1); else printf("%d ",ans[i][j]+1); } } } }; int main() { int n, m, T; scanf("%d",&T); for(int cas = 1; cas <= T; cas++){ scanf("%d%d",&n,&m); for(int i = 0; i < n; i++) scanf("%d",&r[i]); for(int i = 0; i < m; i++) scanf("%d",&c[i]); for(int i = n-1; i > 0; i--) r[i] = r[i]-r[i-1]; for(int i = m-1; i > 0; i--) c[i] = c[i]-c[i-1]; int s, t; s = 0, t = n+m+1; EdmondsKarp ek; ek.init(t); ///s -> r for(int i = 0; i < n; i++) ek.AddEdge(s,i+1,r[i]-m); ///c -> t for(int i = 0; i < m; i++) ek.AddEdge(n+i+1,t,c[i]-n); ///r -> c for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ ek.AddEdge(i+1,n+j+1,19); } } int flow = ek.Maxflow(s,t); printf("Matrix %d\n",cas); ek.n = n, ek.m = m; ek.getMatrix(); } return 0; }
以上是关于UVA11082 Matrix Decompressing 最大流建模解矩阵,经典的主要内容,如果未能解决你的问题,请参考以下文章
UVa 11082 - Matrix Decompressing(最大流)
[题解]UVa 11082 Matrix Decompressing