# 改变

ISAP和dinic一样使用分层标号来规定Dfs的进行方向。但是ISAP进行的是从终点反向标号，这样每次增广到一个点直接提升它的标号即可，把多次Bfs变成了一次Bfs，节省时间

# 代码实现

1 #include <cstdio>
2 #include <queue>
3 #include <cstring>
4 #include <algorithm>
5
6 using std::queue;
7 using std::min;
8 using std::max;
9
10 const int MAXN = 1e4 + 5;
11 const int INF = 0x3f3f3f3f;
12
13 int n, m, s, t;
14
15 struct Edge{
16     int to, val;
17     Edge *next, *opps;
18     Edge(int to, int val, Edge *next):to(to), val(val), next(next){opps = NULL;}
19 };
20
22
23 void AddEdge(int u, int v, int w) {
27 }
28
29 namespace ISAP{
30     int gap[MAXN], dep[MAXN], maxflow = 0;
31     Edge *cur[MAXN];
32
33     void Bfs(int t) {
34         memset(dep, -1, sizeof(dep));
35         memset(gap, 0, sizeof(gap));
36         queue <int> q;
37         dep[t] = 0; gap[0] = 1;
38         q.push(t);
39         while (!q.empty()) {
40             int u = q.front(); q.pop();
41             for (Edge *e = head[u]; e; e = e->next) {
42                 int v = e->to;
43                 if (dep[v] != -1) continue;
44                 q.push(v);
45                 dep[v] = dep[u] + 1;
46                 gap[dep[v]]++;
47             }
48         }
49     }
50
51     int Dfs(int u, int flow) {
52         if (u == t) {
53             maxflow += flow;
54             return flow;
55         }
56         int used = 0;
57         for (Edge *&e = cur[u]; e; e = e->next) {
58             int v = e->to;
59             if (e->val && dep[v] == dep[u] - 1) {
60                 int mi = Dfs(v, min(e->val, flow - used));
61                 if (mi) {
62                     used += mi;
63                     e->val -= mi;
64                     e->opps->val += mi;
65                 }
66                 if (used == flow) return used;
67             }
68         }
69         --gap[dep[u]];
70         if (gap[dep[u]] == 0) dep[s] = n + 1;
72         dep[u]++;
73         ++gap[dep[u]];
74         return used;
75     }
76
77     void Work(int s, int t) {
78         maxflow = 0;
80         Bfs(t);
81         while (dep[s] < n) Dfs(s, INF);
82     }
83 }
84
85 void Pre() {
86     scanf("%d %d %d %d", &n, &m, &s, &t);
88     int x, y, z;
89     for (int i = 1; i <= m; i++) {
90         scanf("%d %d %d", &x, &y, &z);
92     }
93 }
94
95 int main() {
96     Pre();
97     ISAP::Work(s, t);
98     printf("%d\n", ISAP::maxflow);
99     return 0;
100 }
View Code

posted @ 2019-03-09 11:58  Noire02  阅读(236)  评论(0编辑  收藏  举报
Live2D