poj 2396 Budget 有上下界的网络流
2013-10-23 23:11
471 查看
对上下界网络流的解法很多地方有,就不再叙述了,说说自己的理解,网络流的算法能解决分配的问题,而上下界网络流的不同在于下界必须流满,所以做法就是先用网络流算法把下界流满,然后转化成普通网络流算法解决。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=2e2+9,inf=1e9,N=10000,M=1000; int low[maxn][maxn],up[maxn][maxn]; int st[maxn][maxn],ed[maxn][maxn]; int r[maxn],c[maxn]; int n,m; int S,T,SS,TT; int que[N*2],level[N*2]; int head[N*2],lon; bool flag; struct { int w,c,to,next; }e[100000]; void edgeini() { memset(head,-1,sizeof(head)); lon=-1; } void edgemake(int from,int to,int c) { if(from==0||to==0) cout<<lon<<endl; e[++lon].c=c; e[lon].to=to; e[lon].next=head[from]; head[from]=lon; } void make(int rr,int cc,char tmp,int txt) { int ns,nt,ms,mt; if(rr!=0) ns=nt=rr; else ns=1,nt=n; if(cc!=0) ms=mt=cc; else ms=1,mt=m; for(int i=ns;i<=nt;i++) for(int j=ms;j<=mt;j++) { if(tmp=='>') low[i][j]=max(low[i][j],txt+1); else if(tmp=='<') up[i][j]=min(up[i][j],txt-1); else { low[i][j]=max(low[i][j],txt); up[i][j]=min(up[i][j],txt); } } } void makegraph() { edgemake(TT,SS,inf); edgemake(SS,TT,0); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(up[i][j]>=low[i][j]) { edgemake(st[i][j],ed[i][j],up[i][j]-low[i][j]); edgemake(ed[i][j],st[i][j],0); } else flag=false; if(low[i][j]) { edgemake(S,ed[i][j],low[i][j]); edgemake(ed[i][j],S,0); edgemake(st[i][j],T,low[i][j]); edgemake(T,st[i][j],0); } } for(int i=1;i<=n;i++) { edgemake(SS,i+N,r[i]); edgemake(i+N,SS,0); for(int j=1;j<=m;j++) { edgemake(i+N,st[i][j],inf); edgemake(st[i][j],i+N,0); } } for(int i=1;i<=m;i++) { edgemake(i+N+M,TT,c[i]); edgemake(TT,i+N+M,0); for(int j=1;j<=n;j++) { edgemake(ed[j][i],i+N+M,inf); edgemake(i+N+M,ed[j][i],0); } } } bool makelevel(int s,int t) { memset(level,0,sizeof(level)); int front=1,end=0; que[++end]=s; level[s]=1; while(front<=end) { int u=que[front++]; // cout<<u<<endl; if(u==t) return true; for(int k=head[u];k!=-1;k=e[k].next) { int v=e[k].to; if(!level[v]&&e[k].c) { level[v]=level[u]+1; que[++end]=v; } } } return false; } int dfs(int now,int t,int maxf) { if(now==t) return maxf; int ret=0; for(int k=head[now];k!=-1;k=e[k].next) { int u=e[k].to; if(e[k].c==0||level[u]!=level[now]+1) continue; int f=dfs(u,t,min(e[k].c,maxf-ret)); // if(e[k].c<f) cout<<k<<endl; e[k].c-=f; e[k^1].c+=f; ret+=f; if(ret==maxf) return ret; } return ret; } int maxflow(int s,int t) { int ret=0; while(makelevel(s,t)) { ret+=dfs(s,t,inf); } return ret; } void prin() { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { int k=head[st[i][j]]; while(e[k].to!=ed[i][j]) k=e[k].next; printf("%d ",low[i][j]+e[k^1].c); } cout<<endl; } } int main() { // freopen("in.txt","r",stdin); int TTT; scanf("%d",&TTT); while(TTT--) { flag=true; edgeini(); memset(up,50,sizeof(up)); memset(low,0,sizeof(low)); scanf("%d%d",&n,&m); SS=1,TT=2,S=3,T=4; for(int i=1,tt=2;i<=n;i++) for(int j=1;j<=m;j++) { tt++; st[i][j]=tt*2-1; ed[i][j]=tt*2; } for(int i=1;i<=n;i++) scanf("%d",&r[i]); for(int i=1;i<=m;i++) scanf("%d",&c[i]); { int p,rr,cc,txt; char tmp[10]; scanf("%d",&p); while(p--) { scanf("%d%d%s%d",&rr,&cc,tmp+1,&txt); make(rr,cc,tmp[1],txt); } } makegraph(); // for(int i=1;i<=n;i++) // { // for(int j=1;j<=m;j++) // printf("%d ",low[i][j]); // cout<<endl; // } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=m;j++) // printf("%d ",up[i][j]); // cout<<endl; // } // for(int k=head[5];k!=-1;k=e[k].next) // cout<<e[k].to<<endl; // for(int k=head[S];k!=-1;k=e[k].next) // cout<<e[k].c<<endl; if(!flag) { printf("IMPOSSIBLE\n"); continue; } int now=maxflow(S,T); int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum+=low[i][j]; if(sum!=now) { printf("IMPOSSIBLE\n"); continue; } e[0].c=0; e[1].c=0; for(int k=head[S];k!=-1;k=e[k].next) e[k].c=0; for(int k=head[T];k!=-1;k=e[k].next) e[k].c=0; now+=maxflow(SS,TT); int sum1=0,sum2=0; for(int i=1;i<=n;i++) sum1+=r[i]; for(int i=1;i<=m;i++) sum2+=c[i]; if(sum1==sum2&&sum1==now) { prin(); } else { printf("IMPOSSIBLE\n"); } if(TTT) cout<<endl; } return 0; }
相关文章推荐
- POJ 2396 Budget 上下界网络流 经典题
- POJ 2396 Budget 上下界网络流
- POJ 2396:Budget (有流量上下界的网络流)
- poj 2396 Budget (有源汇有上下界的网络流)
- POJ 2396 Budget 上下界网络流
- POJ 2396 Budget 有上下界的网络流
- poj 2396 Budget【有上下界的网络流】
- poj 2396 Budget 带上下界的网络流模型
- 【POJ 2396】 Budget 带上下界网络流 解题报告
- POJ 2396 Budget 上下界网络流
- POJ 2396 Budget (上下界网络流)
- POJ 2396 Budget ——有上下界的网络流
- POJ 2396 Budget 有上下界的可行网络流
- POJ 2396 Budget(有上下界的网络流)
- POJ 2396 Budget 有上下界的网络流
- POJ 2396 Budget 上下界网络流 经典题
- poj 2396 zoj 1994 Budget(有源汇上下界的可行流)
- poj 2396 Budget 很犀利的网络流~
- POJ 2396 Budget【网络流】
- poj 2396 Budget 边容量有上下界的最大流