哭,,终于A了,,wa了一早上。。
输入的时候居然有 0 0的情况,,就是整个矩阵都要满足条件。。
判断可行性后,求最大流的时候,不用砍掉t到s的边,,直接跑s,t的最大流就可以得到真正的最大流
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
#define FIN freopen("input.txt","r",stdin)
#define fuck(x) cout<<x<<endl
const int MX=111111;
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int n,m;
int s,t,S,T;
int head[MX],cnt;
int low[2*MX];
int IN[MX],OUT[MX];
struct Edge
{
int nxt,to,cap;
} E[2*MX];
void edge_init()
{
mem(head,-1);
cnt=0;
}
void edge_add(int u,int v,int cap)
{
E[cnt].nxt=head[u];
E[cnt].to=v;
E[cnt].cap=cap;
head[u]=cnt++;
}
bool vis[MX];
int d[MX],cur[MX];
bool BFS(int s,int t)
{
mem(vis,0);
queue<int> Q;
Q.push(s);
vis[s]=1;
d[s]=0;
d[t]=-1;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(int i=head[u]; ~i; i=E[i].nxt)
{
int v=E[i].to;
if(vis[v]||!E[i].cap) continue;
d[v]=d[u]+1;
vis[v]=1;
Q.push(v);
}
}
return d[t]!=-1;
}
int DFS(int x,int t,int a)
{
if(x==t||a==0) return a;
int flow=0,f;
for(int &i=cur[x]; ~i; i=E[i].nxt)
{
int v=E[i].to;
if(d[v]==d[x]+1&&(f=DFS(v,t,min(a,E[i].cap))))
{
E[i].cap-=f;
E[i^1].cap+=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
}
int Dinic(int s,int t)
{
int flow=0;
while(BFS(s,t))
{
memcpy(cur,head,sizeof(head));
flow+=DFS(s,t,INF);
}
return flow;
}
int G[222][22][2];
int ans[222][22];
int main()
{
FIN;
int cas;
while(cin>>cas)
{
while(cas--)
{
scanf("%d%d",&n,&m);
edge_init();
mem(IN,0);
mem(OUT,0);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) G[i][j][0]=0,G[i][j][1]=INF;
s=0;
t=n+m+1;
S=t+1;
T=S+1;
edge_add(t,s,INF);
edge_add(s,t,0);
int sum1=0,sum2=0;
for(int i=1; i<=n; i++)
{
int x;
scanf("%d",&x);
sum1+=x;
edge_add(s,i,x);
edge_add(i,s,0);
}
for(int i=n+1; i<=m+n; i++)
{
int x;
scanf("%d",&x);
sum2+=x;
edge_add(i,t,x);
edge_add(t,i,0);
}
int k;
scanf("%d",&k);
int sum=0;
for(int i=1; i<=k; i++)
{
int u, v,x;
char s[11];
scanf("%d%d%s%d",&u,&v,&s,&x);
int w1,w2,w11,w22;
if(u)w1=u,w2=u;
else w1=1,w2=n;
if(v)w11=v,w22=v;
else w11=1,w22=m;
for(int ii=w1; ii<=w2; ii++)
for(int jj=w11; jj<=w22; jj++)
if(s[0]=='>') G[ii][jj][0]=max(x+1,G[ii][jj][0]);
else if(s[0]=='=') G[ii][jj][0]=x,G[ii][jj][1]=x;
else G[ii][jj][1]=min(x-1,G[ii][jj][1]);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
IN[j+n]+=G[i][j][0],OUT[i]+=G[i][j][0];
bool flag=1;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
edge_add(i,j+n,G[i][j][1]-G[i][j][0]);
edge_add(j+n,i,0);
}
for(int i=s; i<=t; i++)
if(IN[i]>OUT[i]) edge_add(S,i,IN[i]-OUT[i]),edge_add(i,S,0),sum+=IN[i]-OUT[i];
else if(IN[i]<OUT[i]) edge_add(i,T,OUT[i]-IN[i]),edge_add(T,i,0);
if(flag&&(sum1==sum2)&&(sum==Dinic(S,T))&&(sum1==Dinic(s,t)))
{
for(int i=1; i<=n; i++)
for(int j=head[i]; ~j; j=E[j].nxt)
{
int v=E[j].to;
if(v<=n||v>n+m)continue;
ans[i][v-n]=G[i][v-n][0]+E[j^1].cap;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) printf("%d%c",ans[i][j],j==m?'\n':' ');
cout<<endl;
}
else puts("IMPOSSIBLE\n");
}
}
return 0;
}