最大流 Ford-Fulkerson算法
最大流问题:
管道网络中每条边的最大通过能力(容量)是有限的,实际流量不超过容量。
最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。
Ford-Fulkerson算法:
(1)只利用满足f(e) < c(e)的e或者满足f(e) > 0的e对应的反向边rev(e),寻找一条s到t的路径。
(2)如果不存在满足条件的路径,则结束。否则,沿着该路径尽可能地增加流,放回第(1)步。
f为边的流量,c为边的容量,s为源点,t为汇点。
Ford-Fulkerson算法主要是利用的反向点来算的。假设从A—>B可以流的流量是W,那么从B—>A就可以压回去W流量。
时间复杂度是O(F|E|)。
以HDU3549为例,这个就是标准的最大流问题。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <vector> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 const int MAX = 1010; 8 struct Nod { 9 int to, cap, rev; 10 }; 11 vector<Nod> G[MAX]; 12 bool vis[MAX]; 13 void add_edge(int from, int to, int cap) { 14 G[from].push_back((Nod){to,cap,(int)G[to].size()}); 15 G[to].push_back((Nod){from,0,(int)G[from].size()-1}); 16 } 17 int dfs(int v, int t, int f) { 18 if(v == t) return f; 19 vis[v] = true; 20 for(int i = 0; i < G[v].size(); i ++) { 21 Nod &e = G[v][i]; 22 if(!vis[e.to] && e.cap > 0) { 23 int d = dfs(e.to, t, min(f,e.cap)); 24 if(d > 0) { 25 e.cap -= d; 26 G[e.to][e.rev].cap += d; 27 return d; 28 } 29 } 30 } 31 return 0; 32 } 33 int max_flow(int s, int t){ 34 int flow = 0; 35 while(1) { 36 memset(vis,0,sizeof(vis)); 37 int f = dfs(s, t, INF); 38 if(f == 0) return flow; 39 flow += f; 40 } 41 } 42 int main() { 43 int t, n, m; 44 scanf("%d",&t); 45 for(int k = 1; k <= t; k ++) { 46 scanf("%d %d",&n, &m); 47 while(m--) { 48 int u, v, w; 49 scanf("%d %d %d",&u, &v, &w); 50 add_edge(u,v,w); 51 } 52 printf("Case %d: %d\n",k,max_flow(1,n)); 53 for(int i = 1; i <= n; i ++) G[i].clear(); 54 } 55 return 0; 56 }