最大流最小割算法; BFS搜索增广路径; 算法简单,打印结果也比较清晰;
2010-06-17 14:55
363 查看
#include <iostream> #include <queue> using namespace std; /*********************************/ * 最小割最大流算法 * 可以在求得最大流的同时获取最小割集S,T * 邻接矩阵存储各类信息 /*********************************/ #define INF 1000000 const int MAXN=1000; int cap[MAXN][MAXN]; //容量 ,没有边为0 int flow[MAXN][MAXN]; //流量 int a[MAXN]; //增广路径上最小残流 int p[MAXN]; //增广路前驱 int n; // 顶点数目 int f; //最大流 int s,t; //源点,汇点 /*********************************/ * 邻接矩阵读入图数据 * 例子: 0 16 13 0 0 0 0 0 10 12 0 0 0 4 0 0 14 0 0 0 9 0 0 20 0 0 0 7 0 4 0 0 0 0 0 0 /*********************************/ void readG() { cin>>n; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { cin>>cap[i][j]; } } } /*********************************/ * EdmondsKarp() 最大流最小割算法 * BFS搜索增广路 /*********************************/ void EdmondsKarp() { cin>>s>>t; queue<int> q; memset(flow,0,sizeof(flow)); f=0; for(;;) { memset(a,0,sizeof(a)); a[s]=INF; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=0;v<n;++v) { if(!a[v]&&cap[u][v]-flow[u][v]>0) { p[v]=u; a[v]= (cap[u][v]-flow[u][v]) < a[u] ? (cap[u][v]-flow[u][v]) : a[u]; q.push(v); } } } //没有增广路,算法结束,打印最小割 if(!a[t]) { cout<<"/n/n最小割集S:"; for(int i=0;i<n;++i) { if(a[i]) { cout<<i<<","; } } cout<<"/n最小割集T:"; for(int j=0;j<n;++j) { if(!a[j]) { cout<<j<<","; } } cout<<"/n最大流:"<<f<<endl; break; } for(int u=t;u!=s;u=p[u]) { flow[p[u]][u]+=a[t]; flow[u][p[u]]-=a[t]; } //这条增广路给最大流增加了: f+=a[t]; } } int main() { readG(); EdmondsKarp(); return 0; }
由于BFS能够找到最短路,所以也就保证对于任何情形的图G,均可以在较少的次数内尽快到达汇点T,用DFS不太好.
每次找到一条增广路径, 就给这条路径增流 , 增加的流量就可以计入到最大流内了, 因为不可能从汇点T有回流,所以只要增流的都可以计入最大流. (流网络必须满足有源点和汇点,否则算法应该跑的结果是没有意义的).
初始化时, cap[i][i]=0. cap[i][j]=0 , if(E[i][j]不属于流网络) .
用邻接矩阵存储比较方便, 但是输入量很大.
可以先用静态数组的邻接表录入所有存在容量的边, 然后初始化cap[][]全部为0, 然后根据邻接表, 把有容量的边的容量填到cap[][]里.
这样录入量会小很多, 不必整张cap矩阵都录入, 其中大量的0容量输起来真的很繁琐.
相关文章推荐
- 算法 图中求最小环路径 最小环个数 最大平均环 求简单无向图中环的个数
- 算法 图中求最小环路径 最小环个数 最大平均环 求简单无向图中环的个数
- poj 1273 Drainage Ditches(最大费用流+最短增广路径算法)
- 10000亿数据寻找 最大 或者最小 n个 数 各种算法比较
- 算法8:一个整数数组里怎么同时找最大和最小的数,尽量优化比较次数
- HDOJ 2063 过山车【匈牙利算法求二分图最大匹配 DFS增广 BFS增广】
- hdu 1254 推箱子(bfs判断路径可达+bfs搜索最小)
- 设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。
- HDOJ---1151 Air Raid[匈牙利算法:最小路径覆盖数=原图顶点数–二分图最大匹配数]
- 二叉排序树 插入,创建,中序遍历,最大,最小值,层级,打印,删除,搜索
- poj3020 匈牙利算法+公式:二分无向图的最小路径覆盖 = 顶点数 - 最大二分匹配数 / 2
- 蓝桥杯 算法提高 学霸的迷宫(简单bfs+记录路径)
- POJ 2251 Dungeon Master 比较有趣的三维迷宫bfs搜索路径
- 算法实验一:二分查找算法改进: 当搜索元素x不存在时,返回小于x的最大元素位置i和大于x的最小元素位置j. 当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
- bfs 较为全面的迷宫路径问题,包括路径的打印,起点到任一点的最小步数.
- 最大流问题:增广路径算法的比较之序
- 二分图及其匹配算法——最大匹配数(最小覆盖数)、最大独立数、最小路径覆盖、带权最优匹配
- HD 2063 增广路径求二分图最大匹配(匈牙利算法)
- C之算法--比较两个最大/最小数和9*9乘法口诀
- 最大流问题:增广路径算法的比较之序