最大流-EK(Edmond—Karp)算法
2017-07-25 21:16
429 查看
在图论中,网络流是指在一个每条边都有容量(capacity)的有向图分配流,使一条边的流量不会超过它的容量。
关于增广路:
存在一条分流能够达到汇点,流量为分流中边残余容量的最小值。
关于反向弧:
相当于当另一条分流也走到这个节点时,将多出来的一部分流量推回至其前驱节点并流向前驱节点的另外一条分支。
详细请看:http://blog.csdn.net/fobdddf/article/details/19611065
先贴一份模板
例题:Drainage Ditches
代码:
关于增广路:
存在一条分流能够达到汇点,流量为分流中边残余容量的最小值。
关于反向弧:
相当于当另一条分流也走到这个节点时,将多出来的一部分流量推回至其前驱节点并流向前驱节点的另外一条分支。
详细请看:http://blog.csdn.net/fobdddf/article/details/19611065
先贴一份模板
#include <iostream> #include <queue> #include<string.h> using namespace std; #define arraysize 201 int maxData = 0x7fffffff; int capacity[arraysize][arraysize]; //记录残留网络的容量 int flow[arraysize]; //标记从源点到当前节点实际还剩多少流量可用 int pre[arraysize]; //标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中 int n,m; queue<int> myqueue; int BFS(int src,int des)//每次尝试找一条增广路 { int i,j; while(!myqueue.empty()) //队列清空 myqueue.pop(); for(i=1;i<m+1;++i)//将所有点的前驱节点初始化为-1 { pre[i]=-1; } pre[src]=0;//源点的前驱为0 flow[src]= maxData;//将源点的存储容量初始化为无穷大 myqueue.push(src);//将源点入队 while(!myqueue.empty()) { int index = myqueue.front(); myqueue.pop(); if(index == des) //找到了增广路径 break; for(i=1;i<m+1;++i) { if(i!=src && capacity[index][i]>0 && pre[i]==-1)//如果当前路径残余容量大于0,且这个节点没有被访问过 { pre[i] = index; //记录前驱 flow[i] = min(capacity[index][i],flow[index]); //关键:迭代的找到增量,这条增广路的流量取路径残余容量和前驱节点的已有体积的最小值 myqueue.push(i); } } } if(pre[des]==-1) //残留图中不再存在增广路径 return -1; else return flow[des];//如果存在增广路,则返回这条路的流量 } int maxFlow(int src,int des) { int increasement= 0; int sumflow = 0; while((increasement=BFS(src,des))!=-1)//如果找到一条增广路 { int k = des; //利用前驱寻找路径 while(k!=src) { int last = pre[k]; capacity[last][k] -= increasement; //改变正向边的容量 capacity[k][last] += increasement; //改变反向边的容量 k = last; } sumflow += increasement; } return sumflow; } int main() { int i,j; int start,end,ci; while(cin>>n>>m) { memset(capacity,0,sizeof(capacity)); memset(flow,0,sizeof(flow)); for(i=0;i<n;++i) { cin>>start>>end>>ci; if(start == end) //考虑起点终点相同的情况 continue; capacity[start][end] +=ci; //此处注意可能出现多条同一起点终点的情况 } cout<<maxFlow(1,m)<<endl; } return 0; }
例题:Drainage Ditches
代码:
#include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; #define inf 1<<29 int n,m; int G[205][205];//残余容量图 int flow[205];//分流到这个点的最大流量 int pre[205];//记录前驱节点 int maxflow; int bfs(int scr,int des) { queue<int> q; maxflow=0; while(1) { while(!q.empty()) q.pop(); memset(pre,-1,sizeof(pre)); pre[scr]=0; flow[scr]=inf; q.push(scr); while(!q.empty()) { int top=q.front(); q.pop(); if(top==des) break; for(int i=1;i<=m;i++) { if(i!=scr && pre[i]==-1 && G[top][i]>0) { pre[i]=top; flow[i]=min(flow[top],G[top][i]); q.push(i); } } } if(pre[des]==-1) break; int tmp=des,increase=flow[des]; //printf("->%d\n",increase); while(tmp!=scr) { int last=pre[tmp]; G[last][tmp]-=increase; G[tmp][last]+=increase; tmp=last; } maxflow+=increase; } return maxflow; } int main() { while(~scanf("%d%d",&n,&m)) { memset(G,0,sizeof(G)); memset(flow,0,sizeof(flow)); int u,v,w; for(int i=0;i<n;i++) { scanf("%d%d%d",&u,&v,&w); G[u][v]+=w; } printf("%d\n",bfs(1,m)); } return 0; }
相关文章推荐
- EK(BFS)求最大流的算法模板(邻接表)
- 二分图最大匹配算法-Hopcroft-Karp模板
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES
- HDU3549 Flow Problem【最大流】【Edmond-Karp】
- 最大网络流 EK 算法
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题
- POJ3436--ACM Computer Factory--拆点EK算法求最大流
- POJ 1273 求最大流(Edmond_karp模板题)
- HDU1532 Drainage Ditches【最大流】【Edmond-Karp】
- 网络流最大流EdmondKarp、SAP【模板】
- 最大网络流 EK 算法
- 最大流的增广路算法(EK)
- POJ 1459 构图+最大流(Edmond_karp模版)
- HDU 3549 Flow Problem ( 最大流 -EK 算法)
- 最大流算法---Edmond-Karp
- 《网络流学习笔记02--Edmonds-Karp,Ford-Fulkerson,Dinic三种算法实现最大流》
- 二分图最大匹配hopcroft-karp算法——HDU 2389
- HDU 1532 Drainage Ditches【最大流入门题, EdmondKarp算法】
- 最大流 - Edmonds-Karp 增广路算法
- Power Network--最大流的EK()算法