最大流问题—Ford-Fulkerson
来源:互联网 发布:linux赋予用户权限 编辑:程序博客网 时间:2024/04/29 06:04
一、概念介绍
1、流网络
流网络是一个有向图G=(V,E),图中的每条边(u,v)有一个非负的容量值,表示边(u,v)上可以流进的最大流量。图中有两个特殊的节点:源节点s和汇聚节点t。
流网络有以下几个性质:
容量守恒:流经边(u,v)的流量不能大于(u,v)的容量
流量守恒:除了s和t外,对于其它所有节点都有,流入该节点的流量等于流出该节点的流量
2、最大流
在一个给定的流网络G中,s到t能够通过的最大流量。
3、残存网络
给定一个流网络G和一个流,流的残留网络Gf拥有与原来网络相同的节点。流网络中每条边将对应残留网络中的一条或者两条边,对于流网络中的任意边(u,v),流量为f(u,v),容量为c(u,v):
●如果f(u,v)>0,则在残存网络中包含一条容量为f(u,v)的边(v,u)
●如果f(u,v)<c(u,v),则残存网络中包含一条容量为c(u,v)-f(u,v)的边(u,v)
4、增广路径
已知一个流网络和一个流f,增广路径p是其残存网络Gf上s到t的一条简单路径
二、Ford-Fulkerson方法
Ford-Fulkerson方法的描述:
将残存网络初始化为原网络
while(残存网络中是否还能找到一条增广路径p)
cf=增广路径p上值最小的边的值
更新p上所有的边:(若边(u,v)在p上,则边(u,v)的值-cf,反向边(v,u)的值+cf)
由上述分析可知用Ford-Fulkerson方法求最大流的关键在于寻找残存网络中的增广路径,下面介绍两种算法
1、Edmonds-Karp算法
该算法采用bfs寻找残存网络中的增广路径
Edmonds-karp算法jva模板
int s;//源节点int t;//汇聚节点int n;//节点总个数int[][] graph;//网络图,graph[i][j]=c,表示边(i,j)的容量为c,graph[i][j]==0,表示边(i,j)不存在/** * 判断残余网络rGraph中是否还有增广路径,并将增广路径记录在path中 * @param rGraph * @param path * @return */boolean hasPath(int[][] rGraph,int[] path){int[] vis=new int[n];Queue<Integer> q=new LinkedList<Integer>();q.add(s);vis[s]=1;while(!q.isEmpty()){int top=q.poll();for(int i=0;i<n;i++){if(vis[i]==0 && rGraph[top][i]>0){q.add(i);vis[i]=1;path[i]=top;if(i==t) return true;}}}return false;}int ek(){int max=0;int path[]=new int[n];//纪录增广路径,path[u]=v表示u的前驱节点是vint rGraph[][]=new int[n][n];//残存网络//*//将残存网络初始化为原网络for(int i=0;i<n;i++){for(int j=0;j<n;j++){rGraph[i][j]=graph[i][j];}}//*//while(hasPath(rGraph, path)){int min=0xffff;//**//找到增广路径上的最小边for(int v=t;v!=s;v=path[v]){int u=path[v];min=Math.min(min, rGraph[u][v]); }//**////***//更新增广路径上的边和其反向边for(int v=t;v!=s;v=path[v]){int u=path[v];rGraph[u][v]-=min;rGraph[v][u]+=min;}//***//max+=min;}return max;}
2、Dinic算法
算法流程
Dinic算法java模板
int s;//源节点int t;//汇聚节点int n;//节点的总个数int dis[];//dis[i]=k:表示节点i属于第k层,dis[i]=-1,表示结点i没出现在层次图中int graph[][];//网络图,graph[u][v]=c,表示边(u,v)的容量为c,graph[u][v]=0,表示边(u,v)不存在int rGraph[][];//残存网络/** * bfs()建立层次网络 */boolean bfs(){int vis[]=new int[n];Arrays.fill(dis, -1);Queue<Integer> q=new LinkedList<Integer>();q.add(s);vis[s]=1;dis[s]=0;while (!q.isEmpty()){int top=q.poll();for(int i=0;i<n;i++){if(vis[i]==0 && rGraph[top][i]!=0){dis[i]=dis[top]+1;q.add(i);}}}if(dis[t]>0) return true;else return false;}/** * 寻找增广路径 * @param x * @param min * @return 0表示没找到增广路径 */int dfs(int x,int min){int a=0;if(x==t) return min;for(int i=0;i<n;i++){if(rGraph[x][i]>0 && dis[i]==dis[x]+1 && (a=dfs(i, Math.min(min, rGraph[x][i])))!=0){rGraph[x][i]-=a;rGraph[i][x]+=a;return a;}}return 0;}int dinic(){rGraph=graph;//初始化残存网络int max=0;int a=0;while(bfs())//bfs计算层次图{while((a=dfs(s,0xffff))!=0)//寻找增广路径{max+=a;}}return a;}
- 最大流问题—Ford-Fulkerson
- Ford&Fulkerson 最大流问题
- 最大流问题Ford-Fulkerson方法
- 最大流问题(Ford-Fulkerson算法)
- 最大流问题及Ford-Fulkerson方法
- 最大流问题Ford-Fulkerson方法
- 最大流问题Ford-Fulkerson方法
- 最大流问题之Ford-Fulkerson
- 最大流问题的Ford-Fulkerson解法
- 最大流问题Ford-Fulkerson算法
- Ford-Fulkerson(最大流)
- 最大流问题:最大流的Ford-Fulkerson算法
- Ford-Fulkerson求解最大流
- 最大流 Ford-Fulkerson算法
- 算法 Ford-Fulkerson最大流问题的各种方法
- 增广路算法 Ford-Fulkerson算法 网络最大流问题
- 最大流问题-Ford-Fulkerson算法 C++极简实现
- 网络流——最大流/Ford-Fulkerson算法
- 编码规范-如何写个优美的函数
- shell学习-符号
- Spring AOP
- Educational Codeforces Round 12 E. Beautiful Subarrays
- 程序员,要不要考软考高级职称?
- 最大流问题—Ford-Fulkerson
- polymorphism(多态整理)
- Codeforces Round #338 (Div. 2) C. Running Track(DP)
- 异常控制流
- ionic android 发布
- twitter 设计原理
- androdi wifi log分析关键词总结
- subversion 资料
- ANDROID 开发规范总结