标签:open queue cstring std set cst 之间 nbsp int
题意:给定一个矩阵的前i行的和,以及前i列的和,求任意一个满足条件的矩阵,矩阵元素在[1,20]
矩阵行列<=20
题解:做一个二分图的模型,把行列拆开,然后设源点到行节点的容量就是该行所有元素的和,设汇点到列节点的容量就是该列所有元素的和
然后分别减去列数和行数,再把每个行节点和列节点之间连一条长度为19的边,这样的好处就是全部减了1,流的非负的,从而满足[1,20]
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define MAXN 220 #define INF 0x7f7f7f7f using namespace std; int n,m; int a[MAXN],b[MAXN]; struct Edge{ int from,to,cap,flow; Edge(int u=0,int v=0,int c=0,int f=0){ from=u,to=v,cap=c,flow=f; } }; struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[MAXN<<1]; int b[MAXN<<1]; int d[MAXN<<1]; int cur[MAXN<<1]; void init(int n,int s,int t){ this->n=n; this->s=s,this->t=t; edges.clear(); for(int i=0;i<=n;i++){ G[i].clear(); } } void AddEdge(int x,int y,int cap){ edges.push_back(Edge(x,y,cap,0)); edges.push_back(Edge(y,x,0,0)); m=edges.size(); G[x].push_back(m-2); G[y].push_back(m-1); } bool BFS(){ memset(b,0,sizeof(b)); queue<int> q; d[s]=1; q.push(s); b[s]=1; 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(e.cap>e.flow&&!b[e.to]){ d[e.to]=d[x]+1; q.push(e.to); b[e.to]=1; } } } return b[t]; } int dfs(int x,int a){ if(x==t||!a)return a; int flow=0,f; for(int& i=cur[x];i<G[x].size();i++){ Edge& e=edges[G[x][i]]; if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ edges[G[x][i]].flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(!a){ break; } } } return flow; } int Maxflow(){ int flow=0; while(BFS()){ memset(cur,0,sizeof(cur)); flow+=dfs(s,INF); } return flow; } }D; void init(){ scanf("%d%d",&n,&m); D.init(n+m+1,0,n+m+1); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=m;i++){ scanf("%d",&b[i]); } for(int i=n;i>=1;i--){ a[i]-=a[i-1]; } for(int i=m;i>=1;i--){ b[i]-=b[i-1]; } for(int i=1;i<=n;i++){ D.AddEdge(0,i,a[i]-m); } for(int i=1;i<=m;i++){ D.AddEdge(i+n,n+m+1,b[i]-n); } for(int i=1;i<=n;i++){ for(int j=n+1;j<=n+m;j++){ D.AddEdge(i,j,19); } } } int s[MAXN][MAXN]; int T; void solve(){ D.Maxflow(); for(int i=0;i<D.edges.size();i++){ Edge& e=D.edges[i]; // printf("%d->%d:c=%d f=%d\n",e.from,e.to,e.cap,e.flow); if(1<=e.from&&e.from<=n&&n+1<=e.to&&e.to<=n+m){ s[e.from][e.to-n]=e.flow+1; } } for(int i=1;i<=n;i++){ for(int j=1;j<m;j++){ printf("%d ",s[i][j]); } printf("%d\n",s[i][m]); } printf("\n"); } int main() { // freopen("data.in","r",stdin); scanf("%d",&T); for(int i=1;i<=T;i++){ printf("Matrix %d\n",i); init(); solve(); } return 0; }
标签:open queue cstring std set cst 之间 nbsp int
原文地址:http://www.cnblogs.com/w-h-h/p/7843603.html