## 网络流：最大流之SAP算法

  1 #include <iostream>
2     #include <cstdio>
3     #include <algorithm>
4     #include <queue>
5     #include <cstring>
6
7     using namespace std;
8     const int INF = 0x3f3f3f3f;
9     const int maxn = 200 + 10;
10     const int maxm = 200 + 10;
11
12     int n,m;
14     int tot = 0;
15
16     struct edge
17     {
18       int to;
19       int c;
20       int next;
21       edge(int x = 0, int y = 0, int z = 0) : to(x), c(y), next(z) {}
22      }es[maxm*2];//记录边 注意是2倍
23
24     void add_edge(int u, int v, int c)
25     {
28     }
29
30
31     int SAP(int s, int t)
32     {
33         int numh[maxn],h[maxn],ce[maxn],pre[maxn];
34         //numh 记录gap优化的统计高度数量数组，h 距离标号数组，ce 当前弧，pre前驱数组
35         int f, ans = 0, u, temp, neck, i; //初始化最大流为0
36         memset(h,0,sizeof(h));
37         memset(numh,0,sizeof(numh));
38         memset(pre,-1,sizeof(pre));
39         for(i = 1; i <= n; i++)  ce[i] = head[i];
40         numh[0] = n;
41         u = s;
42         while(h[s] < n)
43         {
44             //寻找增广路
45             if(u == t)
46             {
47                 f = INF;
48                 for(i = s; i != t; i = es[ce[i]].to)
49                 {
50                     if(f > es[ce[i]].c)
51                     {
52                         neck = i;
53                         f = es[ce[i]].c;
54                     }
55                 }
56                 for(i = s; i != t; i = es[ce[i]].to)
57                 {
58                     temp = ce[i];
59                     es[temp].c -= f;
60                     es[temp^1].c += f;
61                 }
62                 ans += f;
63                 u = neck;
64             }
65
66             //寻找可行弧
67             for(i = ce[u]; i != -1; i = es[i].next)
68                 if(es[i].c && h[u] == h[es[i].to] + 1)  break;
69
70            //寻找增广路
71             if(i != -1)
72             {
73                 ce[u] = i;
74                 pre[es[i].to] = u;
75                 u = es[i].to;
76             }
77             else
78             {
79                 if(!--numh[h[u]]) break; //gap optimization
81                 for(temp = n, i = head[u]; i != -1; i = es[i].next)
82                     if(es[i].c)  temp = min(temp, h[es[i].to]);
83
84                 h[u] = temp + 1;
85                 ++numh[h[u]];
86                 if(u != s) u = pre[u];//重标号并且从当前点前驱重新增广
87             }
88
89         }
90         return ans;
91     }
92
93     int main()
94     {
95        while(~scanf("%d%d",&n,&m))
96        {
97        tot = 0;
99        int u,v,c;
100        for(int i = 0; i < m; i++)
101        {
102         scanf("%d%d%d",&u,&v,&c);
110     }