最大流入门 之 poj 1273

//  [5/7/2014 Sjm]
/*
图论之最大流:
Ford-Fulkerson方法 dfs 实现
第一次接触网络流的题目,卡了好久。。。最后终于理解了代码,自己能敲出来了。。。
教训: (体会了算法的思想 != 能写出好的代码) => 要 知行合一
 
对代码细节理解(需要理解的关键位置):
1)对于 void Add_edge(int from, int to, int cap) 函数:
   在构建出 s->t  的正向边后,立即构建 t->s 的反向边(容量为0)
2)dfs 回朔时,正向边与反向边容量变化。
*/
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <vector>
 6 #include <algorithm>
 7 using namespace std;
 8 
 9 const int MAX_M = 200, INF = 0x3f3f3f3f;
10 struct edge { int to, cap, rev; }; 
11 //     边   {终点, 容量, 反向边}
12 vector<edge> G[MAX_M];  // 邻接表构图
13 bool used[MAX_M];  // 用于 dfs 时判断点是否被访问过。
14 
15 // 增加一条
16 void Add_edge(int from, int to, int cap) {
17     edge e1 = { to, cap, G[to].size() };
18     G[from].push_back(e1);  
19     // 增加 from -> to 的正向边
20     edge e2 = { from, 0, G[from].size() - 1 };  
21     // 增加 to -> from 的反向边
22     G[to].push_back(e2);
23 }
24 
25 int Dfs(int v, int t, int f) {
26     if (v == t) return f;
27     used[v] = true;
28     for (int i = 0; i < G[v].size(); i++) {
29         edge &e = G[v][i];
30         if (!used[e.to] && e.cap > 0) {
31             int d = Dfs(e.to, t, min(f, e.cap));
32             if (d > 0) {
33                 e.cap -= d;
34                 // 增流后,正向边容量减少 d
35                 G[e.to][e.rev].cap += d;
36                 // 增流后,反向边容量增加 d
37                 return d;
38             }
39         }
40     }
41     return 0;
42 }
43 
44 int Max_flow(int s, int t) {
45     int max_flow = 0;
46     for (;;) {
47         memset(used, 0, sizeof(used));
48         int f = Dfs(s, t, INF);
49         if (!f) return max_flow;
50         max_flow += f;
51     }
52 }
53 
54 int main()
55 {
56     //freopen("input.txt", "r", stdin);
57     //freopen("output.txt", "w", stdout);
58     int n, m;
59     while (~scanf("%d %d", &n, &m))
60     {
61         for (int i = 0; i < n; i++) {
62             int from, to, flow;
63             scanf("%d %d %d", &from, &to, &flow);
64             Add_edge(from - 1, to - 1, flow);
65         }
66         printf("%d\n", Max_flow(0, m - 1));
67         for (int i = 0; i < m; i++) {
68             G[i].clear();
69         }
70     }
71     return 0;
72 }

 

posted @ 2014-05-07 00:50  JmingS  阅读(111)  评论(0编辑  收藏  举报