UVA11082
2608 ワード
最大ストリームの問題だが...i行目からj列目までの最大ストリームは、(i,j)要素で、弱すぎて、思いもよらなかったでしょう.
同時にノードのcapを計算する場合,1~20の範囲は0~19に変換され,行ごとの値からcを減算し,列ごとの値からrを減算する.
同時にノードのcapを計算する場合,1~20の範囲は0~19に変換され,行ごとの値からcを減算し,列ごとの値からrを減算する.
#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x7fffffff;
struct Edge
{
int from,to,flow,cap;
Edge(int u,int v,int f,int c):from(u),to(v),flow(f),cap(c){}
};
vector<Edge> edges;
vector<int> num[45];
int a[45],p[45];
int r,c,sumr[21],sumc[21],vr[21],vc[21],k;
int map[21][21];
void add(int from,int to,int cap)
{
edges.push_back(Edge(from,to,0,cap));
edges.push_back(Edge(to,from,0,0));
k+=2;
num[from].push_back(k-2);
num[to].push_back(k-1);
}
void maxflow(int s,int t)
{
int x,i;
while(true)
{
memset(a,0,sizeof(a));
queue<int> q;
q.push(s);
a[s]=INF;
while(!q.empty())
{
x=q.front(),q.pop();
for(i=0;i<num[x].size();i++)
{
Edge &e=edges[num[x][i]];
if(!a[e.to]&&e.cap>e.flow)
{
a[e.to]=min(a[x],e.cap-e.flow);
p[e.to]=num[x][i];
q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(i=t;i!=s;i=edges[p[i]].from)
{
edges[p[i]].flow+=a[t];
edges[p[i]^1].flow-=a[t];
}
}
}
void output()
{
int i,j;
for(i=1;i<=r;i++)
for(j=1;j<num[i].size();j++)
map[i][j]=edges[num[i][j]].flow;
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++) cout<<map[i][j]+1<<" ";
cout<<endl;
}
cout<<endl;
}
int main()
{
int T,cnt=0,i,j;
sumr[0]=sumc[0]=0;
scanf("%d",&T);
while(T--)
{
edges.clear();
for(i=0;i<45;i++) num[i].clear();
k=0;
scanf("%d%d",&r,&c);
for(i=1;i<=r;i++)
{
scanf("%d",&sumr[i]);
vr[i]=sumr[i]-sumr[i-1]-c;
add(0,i,vr[i]);
}
for(i=1;i<=c;i++)
{
scanf("%d",&sumc[i]);
vc[i]=sumc[i]-sumc[i-1]-r;
add(r+i,c+r+1,vc[i]);
}
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{
add(i,j+r,19);
}
maxflow(0,r+c+1);
printf("Matrix %d
",++cnt);
output();
}
}