最大网络流(Ford-Fulkerson算法)(hihicoder)
2016-09-14 18:06
316 查看
Ford-Fulkerson算法
(有向图)1.寻找一条从远点到终点的路径
2.找出这条路径里的最短边
3.将这条路径上的边减去 2 中求的最短边 ,其反向的边则加上最短边
4.重复 1 直到无法找到一条从源点到终点的边
至于为什么反向边要加,我是这么理解的:
由于我们找的路径之间可能会交叉,但方向相反,而如果画出实际的网络流图,你会发现这些边会被抵消,从而没有显示。
如图:
在实际中寻找可能会出现这中情况
第一条路径为 1 -> 2 -> 3 -> 4
如果反向边不加的化,就没有路径了,但这是错的;
如果反向边加了的话,
第二条路径就是:1 -> 3 -> 2 -> 4
2 -> 3 和 3 -> 2 正好反向了,实际上也就抵消了;
代码:基于dfs
JAVA代码,下面还有C++的
import java.util.Scanner; import java.util.ArrayList; public class Main { private static Scanner scan = new Scanner(System.in); static final int MAX = 507; static int[][] a = new int[MAX][MAX]; static boolean[] b = new boolean[MAX]; static boolean flag=true; static int ans=0; public static void dfs(int x,int n,int pre[]){ if(x == n)flag = true; for(int i=1;i<=n && !flag;++i){ if(a[x][i] > 0 && b[i] == false){ b[i]=true; pre[i]=x; dfs(i,n,pre); } } } public static void main(String[] args) { int n,m; n = scan.nextInt(); m = scan.nextInt(); int[] pre = new int[n+1]; for(int i=0;i<m;++i){ int x,y,c; x = scan.nextInt(); y = scan.nextInt(); c = scan.nextInt(); a[x][y] += c; } while(flag){ for(int i=0;i<=n;++i)b[i]=false; b[1]=true; pre[1]=1; flag=false; dfs(1,n,pre); if(flag == false)break; int min=Integer.MAX_VALUE; for(int i=n;pre[i]!=i;){ if(a[pre[i]][i]<min)min=a[pre[i]][i]; i = pre[i]; } for(int i=n;pre[i]!=i;){ a[pre[i]][i] -= min; a[i][pre[i]] += min; i = pre[i]; } ans += min; } System.out.println(ans); scan.close(); } }
C++代码
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stack> using namespace std; #define MAX 507 typedef long long ll; int n,m,sum=0,g[MAX][MAX]; vector<int> a[MAX]; bool b[MAX],flag=1; void dfs(int x,int pre[]){ if(x == n)flag=1;; for(int i=0;i<(int)a[x].size() && !flag;++i) if(b[a[x][i]] == false && g[x][a[x][i]] > 0){ b[a[x][i]] = true; pre[a[x][i]] = x; dfs(a[x][i],pre); } } int main(){ int pre[MAX]; cin>>n>>m; for(int i=0;i<m;++i){ int x,y,c; cin>>x>>y>>c; if(g[x][y] == 0)a[x].push_back(y),a[y].push_back(x); g[x][y]+=c; } while(flag){ memset(b,0,sizeof(b)); memset(pre,0,sizeof(pre)); flag=0,b[1]=true,pre[1]=1; dfs(1,pre); if(flag == 0)break; int Min=100000; for(int i=n;pre[i]!=i;){ if(g[pre[i]][i] < Min)Min = g[pre[i]][i]; i = pre[i]; } for(int i=n;pre[i]!=i;){ g[pre[i]][i] -= Min; g[i][pre[i]] += Min; i = pre[i]; } sum += Min; } cout<<sum<<endl; return 0; }
相关文章推荐
- 网络流(一)----最大流Ford-Fulkerson算法
- HDU 3549 Flow Problem(网络流入门题-最大流的Ford-Fulkerson算法)
- 【网络流】最大流最简单的Ford-Fulkerson算法
- 网络流最大流之Ford-Fulkerson算法
- hdu3549(网络流入门题-最大流的Ford-Fulkerson算法)
- 最大网络流之Ford-Fulkerson算法和ScalingFord-Fulkerson算法
- 网络流的征程——Ford-Fulkerson算法
- 最大流问题:最大流的Ford-Fulkerson算法
- poj 1273 Drainage Ditches 【图论-网络流-最大流-Ford-Fulkerson】
- poj 1273 最大流(Ford-Fulkerson算法和Dinic算法分别实现)
- hihocoder#1369 : 网络流一·Ford-Fulkerson算法
- hdu 3549最大流Ford-Fulkerson算法
- [HihoCoder1369]网络流一·Ford-Fulkerson算法
- hdu 3549最大流Ford-Fulkerson算法
- 网络流问题 最大流 ford-fulkerson算法 edmonds-karp算法
- hihocoder1369 网络流一·Ford-Fulkerson算法
- HihoCoder #1369 : 网络流一·Ford-Fulkerson算法
- hdu 1532 Drainage Ditches(最大流之Ford-Fulkerson算法)
- 网络流--ford-fulkerson算法
- hihocoder 1369: 网络流一·Ford-Fulkerson算法