|
3 | 3 | * Tiempo: O(V^2 E)
|
4 | 4 | */
|
5 | 5 |
|
| 6 | +template<typename T> |
6 | 7 | struct Dinic {
|
| 8 | + #define INF numeric_limits<T>::max() |
7 | 9 | struct Edge {
|
8 | 10 | int to, rev;
|
9 |
| - ll c, oc; |
10 |
| - ll flow() { return max(oc - c, 0LL); } // if you need flows |
| 11 | + T c, oc; |
| 12 | + T flow() { return max(oc - c, T(0)); } // if you need flows |
11 | 13 | };
|
12 | 14 | vi lvl, ptr, q;
|
13 | 15 | vector<vector<Edge>> adj;
|
14 | 16 | Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
|
15 |
| - void addEdge(int a, int b, ll c, ll rcap = 0) { |
| 17 | + void addEdge(int a, int b, T c, T rcap = 0) { |
16 | 18 | adj[a].push_back({b, SZ(adj[b]), c, c});
|
17 | 19 | adj[b].push_back({a, SZ(adj[a]) - 1, rcap, rcap});
|
18 | 20 | }
|
19 |
| - ll dfs(int v, int t, ll f) { |
| 21 | + T dfs(int v, int t, T f) { |
20 | 22 | if (v == t || !f) return f;
|
21 | 23 | for (int& i = ptr[v]; i < SZ(adj[v]); i++) {
|
22 | 24 | Edge& e = adj[v][i];
|
23 | 25 | if (lvl[e.to] == lvl[v] + 1)
|
24 |
| - if (ll p = dfs(e.to, t, min(f, e.c))) { |
| 26 | + if (T p = dfs(e.to, t, min(f, e.c))) { |
25 | 27 | e.c -= p, adj[e.to][e.rev].c += p;
|
26 | 28 | return p;
|
27 | 29 | }
|
28 | 30 | }
|
29 | 31 | return 0;
|
30 | 32 | }
|
31 |
| - ll calc(int s, int t) { |
32 |
| - ll flow = 0; |
| 33 | + T calc(int s, int t) { |
| 34 | + T flow = 0; |
33 | 35 | q[0] = s;
|
34 |
| - FOR(L, 0, 31) |
35 |
| - do { // 'int L=30' maybe faster for random data |
| 36 | + FOR(L, 0, 31) do { // 'int L=30' maybe faster for random data |
36 | 37 | lvl = ptr = vi(SZ(q));
|
37 | 38 | int qi = 0, qe = lvl[s] = 1;
|
38 | 39 | while (qi < qe && !lvl[t]) {
|
39 | 40 | int v = q[qi++];
|
40 |
| - for (Edge e : adj[v]) |
41 |
| - if (!lvl[e.to] && e.c >> (30 - L)) |
42 |
| - q[qe++] = e.to, lvl[e.to] = lvl[v] + 1; |
| 41 | + for (Edge e : adj[v]) if (!lvl[e.to] && e.c >> (30 - L)) q[qe++] = e.to, lvl[e.to] = lvl[v] + 1; |
43 | 42 | }
|
44 |
| - while (ll p = dfs(s, t, LLONG_MAX)) flow += p; |
| 43 | + while (T p = dfs(s, t, INF)) flow += p; |
45 | 44 | }
|
46 |
| - while (lvl[t]) |
47 |
| - ; |
| 45 | + while (lvl[t]); |
48 | 46 | return flow;
|
49 | 47 | }
|
50 | 48 | bool leftOfMinCut(int a) { return lvl[a] != 0; }
|
|
0 commit comments