hdu 1532 Drainage Ditches(最大流之Ford-Fulkerson算法)
2015-12-14 00:06
567 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532
一,概念
1)流网络:简单有向图,且有两个特别的顶点(源点s,汇点t)
2)流的边标识为f(u,v)/c(u,v),流量/容量
3)流的三个性质:1>容量限制 对于所有边 流量<容量
2>反对称性 f(u,v)=-f(v,u)
3>流守恒性 正向流与反响流之和为零
4)割:流网络G=(V,E)的割(S,T)将顶点V划分为S和T=V-S两部分,定义割的容量为C(S)割这条线上S中顶点到T中顶点的容量之和
5)残留网络: 残留容量 c f (u, v) = c(u, v) - f (u, v) //边的容量减去边的实际流量
6)增广路径:对于残留网络 G f 中的一条 s-t 路径 p 称其为增广路径
二,最大流和最小割问题
1)最大流:对于一个流网络 G (V , E ) ,其流量 f 的最大值称为最大流,最大流问题就
是求一个流网络的最大流。
2)最小割:是指流网络中容量最小的割
Ford-Fulkerson方法是一种迭代的方法。开始时,对所有的u,v∈V有f(u,v)=0,即初始状态时流的值为0。在每次迭代中,可通过寻找一条“增广路径”来增加流值。增广路径可以看成是从源点s到汇点t之间的一条路径,沿该路径可以压入更多的流,从而增加流的值。反复进行这一过程,直至增广路径都被找出来,根据最大流最小割定理,当不包含增广路径时,f是G中的一个最大流。在算法导论中给出的Ford-Fulkerson的伪代码如下:
hdu 1532:
一,概念
1)流网络:简单有向图,且有两个特别的顶点(源点s,汇点t)
2)流的边标识为f(u,v)/c(u,v),流量/容量
3)流的三个性质:1>容量限制 对于所有边 流量<容量
2>反对称性 f(u,v)=-f(v,u)
3>流守恒性 正向流与反响流之和为零
4)割:流网络G=(V,E)的割(S,T)将顶点V划分为S和T=V-S两部分,定义割的容量为C(S)割这条线上S中顶点到T中顶点的容量之和
5)残留网络: 残留容量 c f (u, v) = c(u, v) - f (u, v) //边的容量减去边的实际流量
6)增广路径:对于残留网络 G f 中的一条 s-t 路径 p 称其为增广路径
二,最大流和最小割问题
1)最大流:对于一个流网络 G (V , E ) ,其流量 f 的最大值称为最大流,最大流问题就
是求一个流网络的最大流。
2)最小割:是指流网络中容量最小的割
Ford-Fulkerson方法是一种迭代的方法。开始时,对所有的u,v∈V有f(u,v)=0,即初始状态时流的值为0。在每次迭代中,可通过寻找一条“增广路径”来增加流值。增广路径可以看成是从源点s到汇点t之间的一条路径,沿该路径可以压入更多的流,从而增加流的值。反复进行这一过程,直至增广路径都被找出来,根据最大流最小割定理,当不包含增广路径时,f是G中的一个最大流。在算法导论中给出的Ford-Fulkerson的伪代码如下:
FORD-FULKERSON(G, s, t) 1 for each edge (u, v) ∈ E[G] 2 do f[u, v] ← 0 3 f[v, u] ← 0 4 while there exists a path p from s to t in the residual network Gf 5 do cf(p) ← min {cf(u, v) : (u, v) is in p} 6 for each edge (u, v) in p 7 do f[u, v] ← f[u, v] + cf(p) 8 f[v, u] ← -f[u, v]
hdu 1532:
#include <limits.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <algorithm> #include <iostream> #include <iterator> #include <sstream> #include <queue> #include <stack> #include <string> #include <vector> #include <list> #include <set> //#define ONLINE_JUDGE #define eps 1e-6 #define INF 0x7fffffff //INT_MAX #define inf 0x3f3f3f3f //int?????????????????? #define FOR(i,a) for((i)=0;i<(a);(i)++) //[i,a); #define MEM(a) (memset((a),0,sizeof(a))) #define sfs(a) scanf("%s",a) #define sf(a) scanf("%d",&a) #define sfI(a) scanf("%I64d",&a) #define pf(a) printf("%d\n",a) #define pfI(a) printf("%I64d\n",a) #define pfs(a) printf("%s\n",a) #define sfd(a,b) scanf("%d%d",&a,&b) #define sft(a,b,c)scanf("%d%d%d",&a,&b,&c) #define for1(i,a,b) for(int i=(a);i<b;i++) #define for2(i,a,b) for(int i=(a);i<=b;i++) #define for3(i,a,b)for(int i=(b);i>=a;i--) #define MEM1(a) memset(a,0,sizeof(a)) #define MEM2(a) memset(a,-1,sizeof(a)) #define MEM3(a) memset(a,0x3f,sizeof(a)) #define MEMS(a) memset(a,'\0',sizeof(a)) #define LL __int64 const double PI = acos(-1.0); template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } template<class T> inline T Min(T a, T b) { return a < b ? a : b; } template<class T> inline T Max(T a, T b) { return a > b ? a : b; } using namespace std; template<class T> T Mint(T a, T b, T c) { if (a>b) { if (c>b) return b; return c; } if (c>a) return a; return c; } template<class T> T Maxt(T a, T b, T c) { if (a>b) { if (c>a) return c; return a; } else if (c > b) return c; return b; } const int maxn=1100; int T,n,m; int vis[maxn]; int si,ei,ci; struct node{ int to;//终点 int cap;//容量 int rev;//反向边 }; vector<node>v[maxn];//邻接链表建图 void addEdge(int a,int b,int c){ v[a].push_back((node){b,c,v[b].size()}); v[b].push_back((node){a,0,v[a].size()-1});//添加反向边 } int dfs(int s,int t,int f){ if(s==t) return f; vis[s]=1; for1(i,0,v[s].size()){ node &tmp=v[s][i]; if(!vis[tmp.to]&&tmp.cap>0){ int d=dfs(tmp.to,t,min(f,tmp.cap)); //对边进行缩减,以便将更多的流从源节点发送到汇点 if(d>0){ tmp.cap-=d;//f(u,v)-d v[tmp.to][tmp.rev].cap+=d;//f'(v,u)+d; return d; } } } return 0; } //如果残存网络中存在增广路,增加流量 int max_flow(int s,int t){ int flow=0; while(1){ MEM1(vis); int f=dfs(s,t,inf); if(f==0) return flow; flow+=f; } } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~sfd(n,m)){ MEM1(v); for1(i,0,n){ sft(si,ei,ci); addEdge(si,ei,ci); } int ans=max_flow(1,m); pf(ans); } return 0; }
相关文章推荐
- Adobe AIR 不能卸载的解决方法
- 怎么区分link和domain
- Daily Scrum 12.13
- pair模板类型
- Daily Scrumming* 2015.12.13(Day 5)
- UVa 442 Matrix Chain Multiplication(矩阵链,模拟栈)
- Determining IP information for eth1... failed; no link present. Check cable? 解决办法
- Determining IP information for eth1... failed; no link present. Check cable? 解决办法
- MINI2440移植xenomai记录
- 机器学习: 朴素贝叶斯(Naive Bayes)
- LeetCode OJ——Submission Details
- Chain of Responsibility(职责链设计模式)
- 【转载】关于RAID 1+0和RAID 0+1的比较
- 从Container内存监控限制到CPU使用率限制方案
- linker command failed with exit code 1 (use -v to see invocation)
- 缩略图Thumbnails
- AIDL
- 静态局部变量 http://baike.baidu.com/link?url=h5FJNxRXfawWPNdJEzqWHpKN1HMk6u8wXLYgg8VYCqgd8MbypeKVeaOgZB0B-
- U盘安装Ubuntu——关于UltraISO打开Ubuntu只有EFI文件夹的解决方法
- VM虚拟机 安装OS X 错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123