標籤:
題目連結:
Matrix Decompressing
題意:
給一個矩陣的每行和每列的和,(給的是前i行或者列的和);
矩陣中每個元素的值在1到20之間,找出這樣的一個矩陣;
思路:
把它轉化成一個二分圖,每行和每列之間連一條弧,然後設定一個源點和一個匯點,源點與行點相連,匯點與列點相連,求一個最大值,當然這是一個有下界的最大流,需要做-1的處理,同時與源匯相連的邊也是要處理的;最後求得的反向邊+1就是答案了;
AC代碼:
#include <bits/stdc++.h>/*#include <iostream>#include <queue>#include <cmath>#include <cstring>#include <algorithm>#include <cstdio>*/using namespace std;#define Riep(n) for(int i=1;i<=n;i++)#define Riop(n) for(int i=0;i<n;i++)#define Rjep(n) for(int j=1;j<=n;j++)#define Rjop(n) for(int j=0;j<n;j++)#define mst(ss,b) memset(ss,b,sizeof(ss));typedef long long LL;const LL mod=1e9+7;const double PI=acos(-1.0);const int inf=0x3f3f3f3f;const int N=1e5+25;int n,m,a[45],b[45],cap[45][45],path[45],flow[45];queue<int>qu;int bfs(){ mst(path,-1); flow[0]=inf; path[0]=0; qu.push(0); while(!qu.empty()) { int fr=qu.front(); qu.pop(); for(int i=1;i<=n+m+1;i++) { if(path[i]==-1&&cap[fr][i]) { flow[i]=min(cap[fr][i],flow[fr]); path[i]=fr; qu.push(i); } } } if(path[n+m+1]==-1)return -1; return flow[n+m+1];}void maxflow(){ int now,pre; while(1) { int temp=bfs(); if(temp==-1)break; now=n+m+1; while(now!=0) { pre=path[now]; cap[pre][now]-=temp; cap[now][pre]+=temp; now=pre; } }}int main(){ int t,Case=1; scanf("%d",&t); while(Case<=t) { mst(cap,0); scanf("%d%d",&n,&m); Riep(n)scanf("%d",&a[i]); Riep(n) { cap[0][i]=a[i]-a[i-1]-m; } Riep(m)scanf("%d",&b[i]); Riep(m) { cap[i+n][n+m+1]=b[i]-b[i-1]-n; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cap[i][j+n]=19; maxflow(); printf("Matrix %d\n",Case++); Riep(n) { Rjep(m-1) printf("%d ",cap[j+n][i]+1); printf("%d\n",cap[m+n][i]+1); } printf("\n"); } return 0;}
UVA-11082 Matrix Decompressing(有上下界的最大流)