代码算是一个模版吧,主要难点是能够看出是个网络流以及如何建图,这还需要做题来积累经验。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/8/15.
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=250+5;
const int INF=100000000;
int cap[maxn][maxn],flow[maxn][maxn],low[maxn][maxn],high[maxn][maxn];
int r[maxn],c[maxn],in[maxn],out[maxn],Layer[maxn],vis[maxn];
int n,m;
void intial()
{
memset(cap,0,sizeof(cap));
memset(flow,0,sizeof(flow));
memset(low,0,sizeof(low));
memset(high,0,sizeof(high));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
}
void Input()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&r[i]);
for(int i=1;i<=m;i++)
scanf("%d",&c[i]);
}
void creat_graph()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
high[i][j+n]=INF;
}
}
int u,v,w;
char ch;
int times;
scanf("%d",×);
while(times--)
{
scanf("%d %d %c %d",&u,&v,&ch,&w);
if(u==0&&v!=0)
{
if(ch=='=')
{
for(int i=1;i<=n;i++)
low[i][v+n]=high[i][v+n]=w;
}
else if(ch=='>')
{
for(int i=1;i<=n;i++)
low[i][v+n]=max(low[i][v+n],w+1);
}
else if(ch=='<')
{
for(int i=1;i<=n;i++)
high[i][v+n]=min(high[i][v+n],w-1);
}
}
else if(u!=0&&v==0)
{
if(ch=='=')
{
for(int i=1;i<=m;i++)
low[u][i+n]=high[u][i+n]=w;
}
else if(ch=='>')
{
for(int i=1;i<=m;i++)
low[u][i+n]=max(low[u][i+n],w+1);
}
else if(ch=='<')
{
for(int i=1;i<=m;i++)
high[u][i+n]=min(high[u][i+n],w-1);
}
}
else if(u==0&&v==0)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(ch=='=') low[i][j+n]=high[i][j+n]=w;
else if(ch=='>') low[i][j+n]=max(low[i][j+n],w+1);
else if(ch=='<') high[i][j+n]=min(high[i][j+n],w-1);
}
}
}
else if(u!=0&&v!=0)
{
if(ch=='=') low[u][v+n]=high[u][v+n]=w;
else if(ch=='>') low[u][v+n]=max(low[u][v+n],w+1);
else if(ch=='<') high[u][v+n]=min(high[u][v+n],w-1);
}
}
int s=0,e=n+m+1;
for(int i=1;i<=n;i++)
low[s][i]=high[s][i]=r[i];
for(int j=1;j<=m;j++)
low[j+n][e]=high[j+n][e]=c[j];
}
bool bfs(int s,int e,int num)
{
memset(Layer,-1,sizeof(Layer));
queue<int> q;
q.push(s);
Layer[s]=0;
while(!q.empty())
{
int v=q.front();
q.pop();
for(int i=0;i<num;i++)
{
if(cap[v][i]&&Layer[i]==-1)
{
Layer[i]=Layer[v]+1;
q.push(i);
}
}
}
if(Layer[e]!=-1) return true;
return false;
}
int dfs(int s,int e,int num)
{
memset(vis,0,sizeof(vis));
int maxflow=0;
vector<int> v;
v.push_back(s);
vis[s]=1;
while(v.size())
{
int nd=v[v.size()-1];
if(nd==e)
{
int minflow=INF,position=0;
for(int i=1;i<v.size();i++)
{
int p1=v[i-1];
int p2=v[i];
if(minflow>cap[p1][p2])
{
minflow=cap[p1][p2];
position=p1;
}
}
maxflow+=minflow;
for(int i=1;i<v.size();i++)
{
int p1=v[i-1];
int p2=v[i];
cap[p1][p2]-=minflow;
cap[p2][p1]+=minflow;
flow[p1][p2]+=minflow;
flow[p2][p1]-=minflow;
}
while(v.size()&&v[v.size()-1]!=position)
{
vis[v[v.size()-1]]=0;
v.pop_back();
}
}
else
{
int i;
for(i=0;i<num;i++)
{
if(cap[nd][i]&&!vis[i]&&Layer[i]==Layer[nd]+1)
{
vis[i]=1;
v.push_back(i);
break;
}
}
if(i>=num) v.pop_back();
}
}
return maxflow;
}
int Dinic(int s,int e,int num)
{
int ans=0;
while(bfs(s,e,num)){
ans+=dfs(s,e,num);
}
return ans;
}
void solve(int s,int e,int num)
{
int ss,ee,sum=0;
ss=num,ee=num+1;
for(int i=0;i<num;i++)
{
for(int j=0;j<num;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(int i=0;i<num;i++)
{
cap[ss][i]=in[i];
cap[i][ee]=out[i];
}
cap[e][s]=INF;
int res=Dinic(ss,ee,num+2);
if(res!=sum)
{
printf("IMPOSSIBLE\n");//坑点啊,一摸一样网页上复制下来的,最后还有个空格,但是交了没AC,最后删了空格AC了
return ;
}
cap[s][e]=cap[e][s]=0;
Dinic(s,e,num);
for(int i=1;i<=n;i++)
{
printf("%d",flow[i][1+n]+low[i][1+n]);
for(int j=2;j<=m;j++)
{
printf(" %d",flow[i][j+n]+low[i][j+n]);
}
printf("\n");
}
}
int main()
{
int t,s,e;
scanf("%d",&t);
while(t--)
{
intial();
Input();
creat_graph();
s=0,e=n+m+1;
solve(s,e,e+1);
printf("\n");
}
return 0;
}