1. 程式人生 > >UVA11082 Matrix Decompressing 最大流建模解矩陣,經典

UVA11082 Matrix Decompressing 最大流建模解矩陣,經典

sizeof mon amp urn 題目 ssi karp memset pro

/**
題目: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 最大流建模解矩陣,經典