有上下界的网络流,非主流做法。
#include<iostream>
#include<fstream>
#include<queue>
using namespace std;
int n;
int c[250][250],pre[250],f[250][250];
int d[250],flow;
int v[250];
typedef struct e{
int data;
e *next;
}e;
e edge[250];
int build(){
int i,j,k;
queue<int> q;
q.push(1);
memset(d,0,sizeof(d));
d[1]=1;
while(!q.empty())
{
i=q.front();
q.pop();
e *p=edge[i].next;
while(p)
{
j=p->data;
if(d[j]==0&&c[i][j]>f[i][j])
{
d[j]=d[i]+1;
if(j==n) return 1;
q.push(j);
}
p=p->next;
}
}
return 0;
}
int find(int m,int minw){
int i,j,k;
if(m==n) return minw;
v[m]=1;
e *p=edge[m].next;
while(p)
{
i=p->data;
if(c[m][i]>f[m][i]&&d[i]==d[m]+1&&v[i]==0)
{
j=find(i,min(minw,c[m][i]-f[m][i]));
if(j)
{
f[m][i]+=j;
f[i][m]=-1*f[m][i];
return j;
}
}
p=p->next;
}
return 0;
}
int solve(){
int i,j,k;
flow=0;
memset(f,0,sizeof(f));
while(build())
while(1){
memset(v,0,sizeof(v));
i=10000000;
k=find(1,i);
flow+=k;
if(k==0) break;
}
return flow;
}
int a[210][21];
int b[210][21];
int h1[210];
int h2[21];
void read(){
// ifstream cin("in.txt");
int i,j,k,s,t,value;
int K,m;
cin>>K;
while(K--)
{
cin>>n>>m;
int sum=0,sum2=0;
memset(edge,0,sizeof(edge));
memset(c,0,sizeof(c));
memset(a,0,sizeof(a));
memset(b,-1,sizeof(b));
memset(h1,0,sizeof(h1));
memset(h2,0,sizeof(h2));
for(i=1;i<=n;i++)
{
cin>>c[1][i+1];
sum+=c[1][i+1];
e *p=new e;
p->data=i+1;
p->next=edge[1].next;
edge[1].next=p;
e* q=new e;
q->data=1;
q->next=edge[i+1].next;
edge[i+1].next=q;
}
for(i=1;i<=m;i++)
{
cin>>c[1+n+i][n+m+2];
sum2+=c[1+n+i][n+m+2];
e *p=new e;
p->data=n+m+2;
p->next=edge[1+n+i].next;
edge[1+n+i].next=p;
e* q=new e;
q->data=1+n+i;
q->next=edge[n+m+2].next;
edge[n+m+2].next=q;
}
if(sum!=sum2)
{
cout<<"IMPOSSIBLE"<<endl<<endl;
continue;
}
cin>>k;
char w;
for(i=1;i<=k;i++)
{
cin>>s>>t>>w>>value;
if(w=='=')
{
if(s==0&&t==0)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=value;
b[i][j]=value;
}
}
else
if(s==0)
{
for(int i=1;i<=n;i++)
{
a[i][t]=value;
b[i][t]=value;
}
}
else
if(t==0)
{
for(int i=1;i<=m;i++)
{
a[s][i]=value;
b[s][i]=value;
}
}
else
{
a[s][t]=value;
b[s][t]=value;
}
}
if(w=='>')
{
value++;
if(s==0&&t==0)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=max(a[i][j],value);
}
}
else
if(s==0)
{
for(int i=1;i<=n;i++)
{
a[i][t]=max(a[i][t],value);
}
}
else
if(t==0)
{
for(int i=1;i<=m;i++)
{
a[s][i]=max(a[s][i],value);
}
}
else
{
a[s][t]=max(a[s][t],value);
}
}
if(w=='<')
{
value--;
if(s==0&&t==0)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(b[i][j]!=-1)
b[i][j]=min(b[i][j],value);
else
b[i][j]=value;
}
}
else
if(s==0)
{
for(int i=1;i<=n;i++)
{
if(b[i][t]!=-1)
b[i][t]=min(b[i][t],value);
else
b[i][t]=value;
}
}
else
if(t==0)
{
for(int i=1;i<=m;i++)
{
if(b[s][i]!=-1)
b[s][i]=min(value,b[s][i]);
else
b[s][i]=value;
}
}
else
{
if(b[s][t]==-1)
b[s][t]=value;
else
b[s][t]=min(b[s][t],value);
}
}
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(b[i][j]==-1)
b[i][j]=1000000;
h1[i]+=a[i][j];
h2[j]+=a[i][j];
c[i+1][j+n+1]=b[i][j]-a[i][j];
e *p=new e;
p->data=j+n+1;
p->next=edge[i+1].next;
edge[i+1].next=p;
e*q=new e;
q->data=i+1;
q->next=edge[j+n+1].next;
edge[j+n+1].next=q;
}
for(i=1;i<=m;i++)
{
c[1][i+n+1]=h2[i];
e *p=new e;
p->data=i+n+1;
p->next=edge[1].next;
edge[1].next=p;
e *q=new e;
q->data=1;
q->next=edge[i+n+1].next;
edge[i+n+1].next=q;
}
for(i=1;i<=n;i++)
{
c[i+1][m+n+2]=h1[i];
e *p=new e;
p->data=n+m+2;
p->next=edge[1+i].next;
edge[1+i].next=p;
e *q=new e;
q->data=i+1;
q->next=edge[m+n+2].next;
edge[m+n+2].next=q;
}
n=n+m+2;
solve();
n-=m+2;
int row[210];
int colon[21];
memset(row,0,sizeof(row));
memset(colon,0,sizeof(colon));
int sum1=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
row[i]+=f[i+1][j+n+1]+a[i][j];
colon[j]+=f[i+1][j+n+1]+a[i][j];
}
}
for(i=1;i<=n;i++)
if(c[1][i+1]!=row[i])
{
sum1=1;
break;
}
if(sum1==0)
for(i=1;i<=m;i++)
if(c[1+n+i][n+m+2]!=colon[i])
{
sum1=1;
break;
}
if(sum1==0)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
cout<<f[i+1][j+n+1]+a[i][j]<<' ';
cout<<endl;
}
cout<<endl;
}
else
cout<<"IMPOSSIBLE"<<endl<<endl;
}
}
int main(){
read();
return 0;
}