题目链接:http://poj.org/problem?id=2396
题意:输入的第一行是测试数据的个数。每组测试数据的第一行是N和M。第二行是N个数,表示N行的和,第三行是M个数,表示M列的和。接下来一个K,表示有以下K个限制,每个限制的形式X Y Z W,其中Z是< > 或者=,表示第X行第Y列的元素和W的大小关系。假如Z是>,那么说明第X行第Y列的元素必须大于W。如果X是0,意思指所有第Y列的数和W的大小关系;如果Y是0,意思指所有第X行的数和W的大小关系;如果X和Y均为0,则表示整个矩阵和W的大小关系。如果有满足所有条件的矩阵,输出;没有的话,输出IMPOSSIBLE。
思路:上下限最大流。
#include <stdio.h>
#include <string.h>
#include <queue>
#define MAX 230
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
const int INF=1000000000;
int high[MAX][MAX],low[MAX][MAX];
int cap[MAX][MAX];
int in[MAX],out[MAX],inc[MAX],pre[MAX],visit[MAX];
int n,m,s,t,ss,tt,sum;
int r[MAX],c[MAX];
void InPut()
{
int i,j,num,u,v,w;
char ch;
memset(high,0,sizeof(high));
memset(low,0,sizeof(low));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&r[i]);
for(i=1;i<=m;i++) scanf("%d",&c[i]);
for(i=1;i<=n;i++)for(j=1;j<=m;j++) high[i][j+n]=INF;
for(scanf("%d",&num);num--;)
{
scanf("%d%d %c%d",&u,&v,&ch,&w);
if(u==0&&v!=0)
{
if(ch=='=')for(i=1;i<=n;i++)low[i][v+n]=high[i][v+n]=w;
else if(ch=='<')for(i=1;i<=n;i++)high[i][v+n]=min(high[i][v+n],w-1);
else for(i=1;i<=n;i++)low[i][v+n]=max(low[i][v+n],w+1);
}
else if(u!=0&&v==0)
{
if(ch=='=')for(i=1;i<=m;i++)low[u][i+n]=high[u][i+n]=w;
else if(ch=='<')for(i=1;i<=m;i++)high[u][i+n]=min(high[u][i+n],w-1);
else for(i=1;i<=m;i++)low[u][i+n]=max(low[u][i+n],w+1);
}
else if(u==0&&v==0)
{
for(i=1;i<=n;i++)for(j=1;j<=m;j++)
{
if(ch=='=') low[i][j+n]=high[i][j+n]=w;
else if(ch=='<')high[i][j+n]=min(high[i][j+n],w-1);
else low[i][j+n]=max(low[i][j+n],w+1);
}
}
else
{
if(ch=='=')low[u][v+n]=high[u][v+n]=w;
else if(ch=='<')high[u][v+n]=min(high[u][v+n],w-1);
else low[u][v+n]=max(low[u][v+n],w+1);
}
}
s=0;t=n+m+1;
for(i=1;i<=n;i++)low[s][i]=high[s][i]=r[i];
for(i=1;i<=m;i++)low[i+n][t]=high[i+n][t]=c[i];
}
int BFS(int s,int t)
{
int i,u;
queue<int> Q;
memset(pre,-1,sizeof(pre));
memset(visit,0,sizeof(visit));
Q.push(s);visit[s]=1;inc[s]=INF;
while(!Q.empty())
{
u=Q.front();
Q.pop();
for(i=0;i<=t;i++) if(!visit[i]&&cap[u][i])
{
inc[i]=min(inc[u],cap[u][i]);
pre[i]=u;
visit[i]=1;
if(i==t) return 1;
Q.push(i);
}
}
return 0;
}
int Maxflow(int s,int t)
{
int maxflow=0,i;
memset(inc,0,sizeof(inc));
while(BFS(s,t))
{
maxflow+=inc[t];
for(i=t;i!=s;i=pre[i])
{
cap[pre[i]][i]-=inc[t];
cap[i][pre[i]]+=inc[t];
}
}
return maxflow;
}
int limitMaxflow()
{
int i,j,ans;
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(cap,0,sizeof(cap));
for(sum=0,i=0;i<=t;i++) for(j=0;j<=t;j++)
{
cap[i][j]=high[i][j]-low[i][j];
out[i]+=low[i][j];
in[j]+=low[i][j];
sum+=low[i][j];
}
for(ss=t+1,tt=t+2,i=0;i<=t;i++) cap[ss][i]=in[i],cap[i][tt]=out[i];
cap[t][s]=INF;
ans=Maxflow(ss,tt);
if(ans!=sum) return 0;
cap[t][s]=cap[s][t]=0;
ans=Maxflow(s,t);
return 1;
}
int C;
int main()
{
for(scanf("%d",&C);C--;)
{
InPut();
if(!limitMaxflow())
{
puts("IMPOSSIBLE");
continue;
}
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++) printf("%d ",cap[j+n][i]+low[i][j+n]);
printf("\n");
}
}
return 0;
}