最大流 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 }

 

posted @ 2017-07-31 18:04  starry_sky  阅读(651)  评论(0编辑  收藏  举报