poj2396 Budget(有源汇的有上下界的可行流)
2017-12-19 08:20
567 查看
有源汇的有上下界的可行流,加一条边t->s,容量为(0,inf)即可转化为无源汇的有上下界的可行流。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> 4000 ; using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 310 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int tst,n,m,b[210][25],c[210][25],h ,num,ss=221,tt=222; int T=301,sn ,sm ,tot,in ,lev ; struct edge{ int to,next,val; }data[100010]; inline void add(int x,int y,int val){ data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val; data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=0; } inline bool build(){ for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ int val=c[i][j]-b[i][j];if(val<0) return 0; add(i,j+n,val);in[j+n]+=b[i][j];in[i]-=b[i][j]; }add(ss,T,tot);add(0,tt,tot);add(tt,ss,inf); for(int i=1;i<=n+m;++i){ if(in[i]>0) add(0,i,in[i]),tot+=in[i]; else if(in[i]<0) add(i,T,-in[i]); }return 1; } inline bool bfs(){ queue<int>q;memset(lev,0,sizeof(lev)); q.push(0);lev[0]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(lev[y]||!data[i].val) continue; lev[y]=lev[x]+1;q.push(y); } }return lev[T]; } inline int dinic(int x,int low){ if(x==T) return low;int tmp=low; for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(lev[y]!=lev[x]+1||!data[i].val) continue; int res=dinic(y,min(tmp,data[i].val)); if(!res) lev[y]=0;else tmp-=res,data[i].val-=res,data[i^1].val+=res; if(!tmp) return low; }return low-tmp; } int main(){ // freopen("a.in","r",stdin); tst=read(); for(int ofo=1;ofo<=tst;++ofo){ if(ofo!=1) puts(""); n=read();m=read();tot=0;num=1;memset(h,0,sizeof(h)); int totm=0,ans=0;memset(in,0,sizeof(in)); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) c[i][j]=inf,b[i][j]=0; for(int i=1;i<=n;++i) tot+=sn[i]=read(),add(ss,i,0),in[i]+=sn[i]; for(int i=1;i<=m;++i) totm+=sm[i]=read(),add(i+n,tt,0),in[i+n]-=sm[i]; int owo=read(); while(owo--){ int x=read(),y=read();char op[5];scanf("%s",op+1);int val=read(); if(x==0&&y==0){ if(op[1]=='='){ for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) b[i][j]=max(b[i][j],val),c[i][j]=min(c[i][j],val); }if(op[1]=='>'){ for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) b[i][j]=max(b[i][j],val+1); }if(op[1]=='<'){ for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) c[i][j]=min(c[i][j],val-1); }continue; }if(x==0){ if(op[1]=='='){ for(int i=1;i<=n;++i) b[i][y]=max(b[i][y],val),c[i][y]=min(c[i][y],val); }if(op[1]=='>'){ for(int i=1;i<=n;++i) b[i][y]=max(b[i][y],val+1); }if(op[1]=='<'){ for(int i=1;i<=n;++i) c[i][y]=min(c[i][y],val-1); }continue; }if(y==0){ if(op[1]=='='){ for(int i=1;i<=m;++i) b[x][i]=max(b[x][i],val),c[x][i]=min(c[x][i],val); }if(op[1]=='>'){ for(int i=1;i<=m;++i) b[x][i]=max(b[x][i],val+1); }if(op[1]=='<'){ for(int i=1;i<=m;++i) c[x][i]=min(c[x][i],val-1); }continue; } if(op[1]=='=') b[x][y]=max(b[x][y],val),c[x][y]=min(c[x][y],val); if(op[1]=='>') b[x][y]=max(b[x][y],val+1); if(op[1]=='<') c[x][y]=min(c[x][y],val-1); }if(tot!=totm||!build()){puts("IMPOSSIBLE");continue;} while(bfs()) ans+=dinic(0,inf); if(ans!=tot){puts("IMPOSSIBLE");continue;} for(int x=1;x<=n;++x){ for(int i=h[x];i;i=data[i].next){ int y=data[i].to-n;if(y<1||y>m) continue; b[x][y]+=data[i^1].val; } }for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ printf("%d",b[i][j]);putchar(j==m?'\n':' '); } }return 0; }
相关文章推荐
- poj 2396 Budget--有源汇+有上下界+可行流
- POJ 2396 - Budget 有源汇的上下界可行流
- POJ 2396 Budget 有源汇有上下界的可行流
- poj 2396 zoj 1994 Budget(有源汇上下界的可行流)
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
- 【有源汇有上下界可行流】POJ-2396(ZOJ-1994) Budget
- poj 2396 Budget(有源汇上下界可行流)
- poj 2396 Budget(有源汇上下界可行流)
- POJ 2396 有上下界有源汇可行流
- 【POJ 2396 Budget】 有上下界的可行流
- poj 2396(有源汇的上下界可行流。。。。。dinic)
- POJ 2396 Budget (有源汇有上下界最大流)
- poj 2396 Budget (有源汇有上下界的网络流)
- POJ 2396 Budget(无源汇网络有上下界的可行流-Dinic)
- POJ 2396 有源汇的上下界可行流(好题)
- poj 2396(有源汇的上下界可行流。。。。。dinic)
- POJ 2396 有源有汇有上下界可行流问题
- POJ 2396 Budget 有上下界的可行流
- POJ 2396 有源有汇有上下界可行流问题
- POJ 2396 Budget 有上下界的可行网络流