从零单练网络流 第三章 有上下界的可行流
来源:互联网 发布:淘宝网男士休闲鞋 编辑:程序博客网 时间:2024/05/26 17:48
可行流无非就是把给定的一些条件转化为最大流可以完成的任务,著名的题目有SGU上的两道题P194 Reactor Cooling和P176 Flow Construction。第一题我本想依靠自己想出最大流的模型,不过最后还是看了题解。
这里简要讲一下P194 Reactor Cooling这道题的解法,这题在ACdream上也有,P1211。题意大概为给你n个点,m条边,每条边有上下界流,然后要保证每个点出流和入流一样。
建立超级源st和超级汇tr,对于每条边的容量为自己上下界流之差,记录每个点入出流情况。假如入流多,那st到该点加一条边即多出来的入流,反之,就该点引边向tr,值是这个绝对值。至于为什么这样,只有自己模拟一遍,自己说服自己了,说实在是说不清楚。不过有一点可以帮助你理解,这道题判断是否可行,是要st每条边都满流,之前因为st的边是由入流情况决定的,而其他边是上下界之差,即其他边是忽略了下界的判断的,那所有关于下界的判断全部集中于st引出的边,st引出的边正是保证他们下界之上的关键,而上下界之差的边则控制了上界。那为什么st引出的边保证了他们下界之上呢?因为假如每条边都是下界,那有些点必溢出,这些溢出的流则由超级源提供了。上下界之差控制上界应该好理解。
你理解了吗?
Reactor Cooling的代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<ctime>#include<string>#include<cstring>#include<algorithm>#include<fstream>#include<queue>#include<stack> #include<vector>#include<cmath>#include<iomanip>#define rep(i,n) for(i=1;i<=n;i++)#define MM(a,t) memset(a,t,sizeof(a))#define INF 1e9typedef long long ll;#define mod 1000000007using namespace std; int n,m,np,nc,st,tr; int res;struct edge{ int s,e,lest;}eg[40020];int w[220][220],inout[220];int gap[220],dis[220],pre[220];queue<int> Q;void BFS(){int i,j;MM(gap,0); MM(dis,0);dis[tr]=0; gap[0]=1;while(!Q.empty()) Q.pop(); Q.push(tr);while(!Q.empty()){int s,e=Q.front(); Q.pop();for(s=0;s<=n;s++)if(!dis[s] && w[s][e]){dis[s]=dis[e]+1;gap[dis[s]]++; Q.push(s);}} //for(i=0;i<=n;i++) cout<<dis[i]<<' '; cout<<'\n';}int ISAP(){ BFS(); int i,u=st,j,ans=0,md; pre[st]=-1; while(dis[u]<=n){ if(u==tr){ int minflow=INF; for(i=pre[u];i!=-1;u=i,i=pre[i]) minflow=min(minflow,w[i][u]);for(i=pre[u=tr];i!=-1;u=i,i=pre[i]){w[i][u]-=minflow;w[u][i]+=minflow;}ans+=minflow; } for(i=0;i<=n;i++) if(w[u][i]>0 && dis[i]+1==dis[u]) break; if(i<=n){ pre[i]=u; u=i; } else{ if(--gap[dis[u]]==0) break; for(md=n,i=0;i<=n;i++) if(w[u][i]>0) md=min(md,dis[i]); dis[u]=md+1; gap[dis[u]]++; if(u!=st) u=pre[u]; } } return ans;}int main(){int i,j,i1,i2,i3;string si; while(scanf("%d%d",&n,&m)!=EOF){ MM(w,0); MM(inout,0); rep(i,m){ int s,e,v1,v2; scanf("%d%d%d%d",&s,&e,&v1,&v2); eg[i].s=s; eg[i].e=e; eg[i].lest=v1; inout[s]-=v1; inout[e]+=v1; w[s][e]=v2-v1; } st=0; tr=n+1; n++; rep(i,n-1) if(inout[i]<0) w[i][tr]=-inout[i]; else w[st][i]=inout[i]; ISAP(); bool ff=true; rep(i,n-1) if(w[st][i]!=0){ ff=false;break; } if(!ff) printf("NO\n"); else{ printf("YES\n");rep(i,m) printf("%d\n",eg[i].lest+w[eg[i].e][eg[i].s]); } }return 0;}
0 0
- 从零单练网络流 第三章 有上下界的可行流
- POJ 2396 Budget 有上下界的可行网络流
- 容量有上下界的可行流
- POJ 2396 Budget(无源汇网络有上下界的可行流-Dinic)
- poj 2396(有上下界的可行流)
- poj 2396(有上下界的 可行流)
- hdu4940 有上下界的无源可行流判断
- POJ 2396 Budget 有上下界的可行流
- 有上下界的网络流
- 【有上下界的网络流】
- 有上下界限制的网络流
- 有上下界的网络流专辑
- 有上下界的网络流问题
- 有上下界的网络流
- 有上下界的网络流
- 有上下界的网络流问题
- 有上下界的网络流
- 有上下界的网络流
- 用C#把批处理文件改为windows系统服务(简单的C#编写系统服务教程)
- 网络推广1000招 第42招
- java学习二 java开发环境搭建
- mybatis实战教程(mybatis in action),mybatis入门到精通
- 修复Ubuntu linux启动项
- 从零单练网络流 第三章 有上下界的可行流
- android 解决输入法键盘遮盖布局问题
- css hack用法总结
- Android错误之Unable to execute dex: java.nio.BufferOverflowException.
- N-Queens II
- HDU 4307 Matrix 最小割 矩阵乘法展开
- 结合2012.10版本的u-boot分析SD卡驱动(笔记)
- BZOJ 2002 LCT
- java学习一 java程序运行过程