POJ2396【上下界网络流】

感觉细节挺多的.
/* I will wait for you */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>

typedef long long LL;
typedef unsigned long long ULL;

using namespace std;

const int maxn=410;
const int maxm=1010;
const int maxs=26;
const int INF=1000000000;
const int P=1000000007;
const double error=1e-9;

int cap[maxn][maxn],flow[maxn][maxn],up[maxn][maxn],down[maxn][maxn],in[maxn],out[maxn];
int n,m,S,T,nS,nT,vis[maxn],dis[maxn],cur[maxn];

void init()
{
	memset(cap,0,sizeof(cap));
	memset(flow,0,sizeof(flow));
	memset(up,0,sizeof(up));
	memset(down,0,sizeof(down));
	memset(in,0,sizeof(in));
	memset(out,0,sizeof(out));
}

void read()
{
	scanf("%d%d",&n,&m);
	
	S=0;T=n+m+1;
	
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) up[i][n+j]=INF;
	
	for(int i=1,c;i<=n;i++) scanf("%d",&c),up[S][i]=down[S][i]=c;
	
	for(int i=1,c;i<=m;i++) scanf("%d",&c),up[n+i][T]=down[n+i][T]=c;
	
	int q;scanf("%d",&q);
	for(int t=0;t<q;t++)
	{
		int x,y,c;char s[10];
		scanf("%d%d%s%d",&x,&y,s,&c);
		
		int xl,xr,yl,yr;
		x?xl=xr=x:(xl=1,xr=n);
		y?yl=yr=y:(yl=1,yr=m);
		
		for(int i=xl;i<=xr;i++) for(int j=yl;j<=yr;j++)
		{
			if(s[0]=='=') up[i][n+j]=down[i][n+j]=c;
			if(s[0]=='>') down[i][n+j]=max(down[i][n+j],c+1);
			if(s[0]=='<') up[i][n+j]=min(up[i][n+j],c-1);
		}
	}
}

bool bfs(int s,int t)
{
	memset(vis,0,sizeof(vis));
	memset(dis,-1,sizeof(dis));
	queue<int> q;q.push(s);
	dis[s]=vis[s]=1;
	
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=0;i<=t;i++) if(cap[u][i]>0&&!vis[i]) vis[i]=1,dis[i]=dis[u]+1,q.push(i);
	}
	
	return dis[t]!=-1;
}

int dfs(int u,int a,int t)
{
	if(u==t) return a;
	int f,ans=0;
	
	for(int i=0;a&&i<=t;i++) if(cap[u][i]>0&&dis[i]==dis[u]+1)
	{
		f=dfs(i,min(a,cap[u][i]),t);
		cap[u][i]-=f;flow[u][i]+=f;
		cap[i][u]+=f;flow[i][u]-=f;
		ans+=f;a-=f;
	}
	
	if(!ans) dis[u]=-1;
	return ans;
}

int dinic(int s,int t)
{
	int ans=0;
	while(bfs(s,t)) ans+=dfs(s,INF,t);
	return ans;
}

void work()
{
	int sum=0;nS=n+m+2;nT=n+m+3;
	
	for(int i=S;i<=T;i++) for(int j=S;j<=T;j++)
	{
		cap[i][j]=up[i][j]-down[i][j];
		out[i]+=down[i][j];in[j]+=down[i][j];
		sum+=down[i][j];
	}
	
	for(int i=S;i<=T;i++) cap[nS][i]=in[i],cap[i][nT]=out[i];
	
	cap[T][S]=INF;int ans=dinic(nS,nT);

	if(ans!=sum) printf("IMPOSSIBLE\n");
	else
	{
		cap[S][T]=cap[T][S]=0;dinic(S,T);
		for(int i=1;i<=n;i++,putchar(10)) for(int j=1;j<=m;j++) printf("%d ",flow[i][n+j]+down[i][n+j]);
	}
}
		

int main()
{
	int t;scanf("%d",&t);
	for(int i=1;i<=t;i++) init(),read(),work();
	return 0;
}

你可能感兴趣的:(POJ2396【上下界网络流】)