题目链接:http://poj.org/problem?id=2396
题目大意:求一个矩阵,行和,列和都有限制,同时点的值也有限制,求可行流。
题目思路:有上下界可行流问题,哎,变量打错,wrong 了好久啊。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 5500
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int dis[Max],gap[Max],pre[Max],cur[Max],p[Max];
int in[Max],out[Max];
int n,m,s,t,eid;
int id[220][22];
int mp[220][22][2];
struct node
{
int to,next,c;
}e[4*40400];
void addedge(int u,int v,int c)
{
e[eid].to=v;
e[eid].c=c;
e[eid].next=p[u];
p[u]=eid++;
}
int ISAP(int st,int ed,int n) ///起点,终点,顶点数
{
memset(dis, 0, sizeof(dis));
memset(gap, 0, sizeof(gap)); gap[0]=n;
memcpy(cur, p, sizeof(p)); ///memcpy!
int i,flag,v,u=pre[st]=st,maxflow=0,aug=inf; //puts("akk");
while(dis[st] < n)
{
for(flag=0,i=cur[u];i!=-1; i=e[i].next) /// cur[u]
if(e[i].c&& dis[u] == dis[e[i].to]+1)
{
flag = 1;
break;
}
if(flag)
{
if(aug > e[i].c)
aug = e[i].c;
v = e[i].to;
pre[v] = u;
cur[u] = i;
u = v;
if(u == ed)
{
for(u=pre[u]; 1;u=pre[u]) ///notice!
{
e[cur[u]].c -= aug;
e[cur[u]^1].c += aug;
if(u==st) break;
}
maxflow += aug;
aug = inf;
}
}
else
{
int minx = n;
for(i=p[u]; i!=-1; i=e[i].next)
if(e[i].c&& dis[e[i].to]<minx)
{
minx = dis[e[i].to];
cur[u] = i;
}
if(--gap[dis[u]] == 0)
break;
dis[u] = minx+1;
gap[dis[u]]++;
u = pre[u];
}
}
return maxflow;
}
char op[10];
int main()
{
// freopen("C:/Users/Administrator/Desktop/my.txt","w",stdout);
int m,n,count=-1,sum,ca;
int u,v,i,j,k,x,y,tp,q,s,t,ss,tt;
scanf("%d",&ca);
while(ca--)
{
count++;
scanf("%d%d",&n,&m);
memset(p,-1,sizeof(p));
eid=0;
sum=0;
int sum1=0,sum2=0;
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
ss=0;tt=n+m+1;
for(i=1;i<=n;i++)
{
scanf("%d",&in[i]);
sum1+=in[i];
}
for(i=1;i<=m;i++)
{
scanf("%d",&out[i+n]);
sum2+=out[i+n];
}
scanf("%d",&q);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
mp[i][j][0]=0;
mp[i][j][1]=inf;
}
int num,a,b,c,d;
for(i=0;i<q;i++)
{
scanf("%d%d%s%d",&u,&v,op,&num);
if(u==0&&v==0){a=1;b=n;c=1;d=m;}
else if(u==0){a=1;b=n;c=v;d=v;}
else if(v==0){a=u;b=u;c=1;d=m;}
else{a=b=u;c=d=v;}
for(x=a;x<=b;x++)
for(y=c;y<=d;y++)
{
if(op[0]=='>')
mp[x][y][0]=max(mp[x][y][0],num+1);
else if(op[0]=='<')
mp[x][y][1]=min(mp[x][y][1],num-1);
else
{
mp[x][y][0]=max(mp[x][y][0],num);
mp[x][y][1]=min(mp[x][y][1],num);
}
}
}
int flag=0;
if(sum1!=sum2)
flag=1;
for(i=1;i<=n&&!flag;i++)
for(j=1;j<=m;j++)
{
if(mp[i][j][0]>mp[i][j][1])
{
flag=1;
break;
}
out[i]+=mp[i][j][0];
in[j+n]+=mp[i][j][0];
addedge(i,j+n,mp[i][j][1]-mp[i][j][0]);
id[i][j]=eid;
addedge(j+n,i,0);
}
if(flag)
{
printf("IMPOSSIBLE\n");
if(ca)
puts("");
continue;
}
for(i=1;i<=n+m;i++)
{
addedge(ss,i,in[i]);
addedge(i,0,0);
addedge(i,tt,out[i]);
addedge(tt,i,0);
sum+=in[i];
}
if(ISAP(ss,tt,n+m+2)==sum)
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(j==m)
printf("%d\n",e[id[i][j]].c+mp[i][j][0]);
else
printf("%d ",e[id[i][j]].c+mp[i][j][0]);
}
}
else
printf("IMPOSSIBLE\n");
if(ca)
puts("");
}
}