身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了。
Network Flow - Maximum Flow
Time Limit : 1 sec, Memory Limit : 65536 KBJapanese version is here
1 #include <bits/stdc++.h> 2 3 #define fread_siz 1024 4 5 inline int get_c(void) 6 { 7 static char buf[fread_siz]; 8 static char *head = buf + fread_siz; 9 static char *tail = buf + fread_siz; 10 11 if (head == tail) 12 fread(head = buf, 1, fread_siz, stdin); 13 14 return *head++; 15 } 16 17 inline int get_i(void) 18 { 19 register int ret = 0; 20 register int neg = false; 21 register int bit = get_c(); 22 23 for (; bit < 48; bit = get_c()) 24 if (bit == '-')neg ^= true; 25 26 for (; bit > 47; bit = get_c()) 27 ret = ret * 10 + bit - 48; 28 29 return neg ? -ret : ret; 30 } 31 32 template <class T> 33 inline T min(T a, T b) 34 { 35 return a < b ? a : b; 36 } 37 38 const int inf = 2e9; 39 const int maxn = 20005; 40 41 int n, m; 42 int s, t; 43 44 int edges; 45 int hd[maxn]; 46 int to[maxn]; 47 int nt[maxn]; 48 int fl[maxn]; 49 50 inline void add(int u, int v, int f) 51 { 52 nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; hd[u] = edges++; 53 nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; hd[v] = edges++; 54 } 55 56 int dep[maxn]; 57 58 inline bool bfs(void) 59 { 60 static int que[maxn]; 61 static int head, tail; 62 63 memset(dep, 0, sizeof(dep)); 64 head = 0, tail = 0; 65 que[tail++] = s; 66 dep[s] = 1; 67 68 while (head != tail) 69 { 70 int u = que[head++], v; 71 for (int i = hd[u]; ~i; i = nt[i]) 72 if (!dep[v = to[i]] && fl[i]) 73 dep[v] = dep[u] + 1, que[tail++] = v; 74 } 75 76 return dep[t]; 77 } 78 79 inline int dfs(int u, int f) 80 { 81 if (u == t || !f) 82 return f; 83 84 int used = 0, flow, v; 85 86 for (int i = hd[u]; ~i; i = nt[i]) 87 if (dep[v = to[i]] == dep[u] + 1 && fl[i]) 88 { 89 flow = dfs(v, min(f - used, fl[i])); 90 91 used += flow; 92 fl[i] -= flow; 93 fl[i^1] += flow; 94 95 if (used == f) 96 return f; 97 } 98 99 if (!used) 100 dep[u] = 0; 101 102 return used; 103 } 104 105 inline int dinic(void) 106 { 107 int maxFlow = 0, newFlow; 108 109 while (bfs()) 110 while (newFlow = dfs(s, inf)) 111 maxFlow += newFlow; 112 113 return maxFlow; 114 } 115 116 signed main(void) 117 { 118 n = get_i(); 119 m = get_i(); 120 121 memset(hd, -1, sizeof(hd)); 122 123 for (int i = 1; i <= m; ++i) 124 { 125 int u = get_i(); 126 int v = get_i(); 127 int f = get_i(); 128 add(u, v, f); 129 } 130 131 s = 0, t = n - 1; 132 133 printf("%d ", dinic()); 134 }
Network Flow - Minimum Cost Flow
Time Limit : 1 sec, Memory Limit : 65536 KB最小費用流
各辺にコストが設定されたフローネットワークにおいて、始点 ss から終点 tt まで流用 FF のフローを流すための最小コストを求めてください。
フローネットワークの各辺 ee には容量 c(e)c(e) 及びコスト d(e)d(e) が設定されています。各辺 ee には容量 c(e)c(e)を超えない流量 f(e)f(e) のフローを流すことができます。始点 ss から終点 tt へ流量 FF のフローを流したときの、∑e(f(e)×d(e))∑e(f(e)×d(e)) の最小値を求めてください。
入力
フローネットワーク G(V,E)G(V,E) が以下の形式で与えられる。
|V||E|F|V||E|F
u0v0c0d0u0v0c0d0
u1v1c1d1u1v1c1d1
:
u|E|1v|E|−1c|E|−1d|E|−1u|E|1v|E|−1c|E|−1d|E|−1
|V||V|, |E||E|, FF はそれぞれフローネットワーク GG の頂点の数、辺の数、流したい流量を示す。 GG の頂点にはそれぞれ 0,1,...,|V|−10,1,...,|V|−1 の番号が付けられており、始点を 0、終点を |V|−1|V|−1 とする。
uiui, vivi, cici, didi はフローネットワーク GG の ii 番目の辺を表し、頂点 uiui から頂点 vivi に向かって容量が cici でコストが didi の辺があることを表す。
出力
最小費用流を1行に出力する。ただし、始点 ss から終点 tt へ流量 FF のフローを流すことができない場合は -1 を1行に出力する。
制約
- 2 ≤ |V||V| ≤ 100
- 1 ≤ |E||E| ≤ 1000
- 0 ≤ FF ≤ 1000
- 0 ≤ cici, didi ≤ 1000
- uiui ≠≠ vivi
- 頂点 xx から頂点 yy に向かって辺がある場合、頂点 yy から頂点 xx に向かう辺(逆辺)はない。
入力例
4 5 2 0 1 2 1 0 2 1 2 1 2 1 1 1 3 1 3 2 3 2 1
出力例
6
1 #include <bits/stdc++.h> 2 3 #define fread_siz 1024 4 5 inline int get_c(void) 6 { 7 static char buf[fread_siz]; 8 static char *head = buf + fread_siz; 9 static char *tail = buf + fread_siz; 10 11 if (head == tail) 12 fread(head = buf, 1, fread_siz, stdin); 13 14 return *head++; 15 } 16 17 inline int get_i(void) 18 { 19 register int ret = 0; 20 register int neg = false; 21 register int bit = get_c(); 22 23 for (; bit < 48; bit = get_c()) 24 if (bit == '-')neg ^= true; 25 26 for (; bit > 47; bit = get_c()) 27 ret = ret * 10 + bit - 48; 28 29 return neg ? -ret : ret; 30 } 31 32 template <class T> 33 inline T min(T a, T b) 34 { 35 return a < b ? a : b; 36 } 37 38 const int inf = 2e9; 39 const int maxn = 2005; 40 41 int n, m; 42 int s, t; 43 int flow; 44 45 int edges; 46 int hd[maxn]; 47 int nt[maxn]; 48 int to[maxn]; 49 int vl[maxn]; 50 int fl[maxn]; 51 52 inline void add(int u, int v, int f, int w) 53 { 54 nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; vl[edges] = +w; hd[u] = edges++; 55 nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; vl[edges] = -w; hd[v] = edges++; 56 } 57 58 int dis[maxn]; 59 int pre[maxn]; 60 61 inline bool spfa(void) 62 { 63 static int que[maxn]; 64 static int inq[maxn]; 65 static int head, tail; 66 67 memset(dis, 0x3f, sizeof(dis)); 68 head = 0, tail = 0; 69 que[tail++] = s; 70 pre[s] = -1; 71 inq[s] = 1; 72 dis[s] = 0; 73 74 while (head != tail) 75 { 76 int u = que[head++], v; inq[u] = 0; 77 78 for (int i = hd[u]; ~i; i = nt[i]) 79 if (dis[v = to[i]] > dis[u] + vl[i] && fl[i]) 80 { 81 dis[v] = dis[u] + vl[i]; 82 pre[v] = i ^ 1; 83 if (!inq[v]) 84 inq[v] = 1, que[tail++] = v; 85 } 86 } 87 88 return dis[t] < 0x3f3f3f3f; 89 } 90 91 inline int expend(void) 92 { 93 int newFlow = inf; 94 95 for (int i = pre[t]; ~i; i = pre[to[i]]) 96 newFlow = min(newFlow, fl[i ^ 1]); 97 98 for (int i = pre[t]; ~i; i = pre[to[i]]) 99 fl[i] += newFlow, fl[i^1] -= newFlow; 100 101 return flow -= newFlow, newFlow * dis[t]; 102 } 103 104 inline int mcmf(void) 105 { 106 int ret = 0; 107 108 while (spfa()) 109 ret += expend(); 110 111 return flow ? -1 : ret; 112 } 113 114 signed main(void) 115 { 116 n = get_i(); 117 m = get_i(); 118 119 flow = get_i(); 120 121 memset(hd, -1, sizeof(hd)); 122 123 for (int i = 1; i <= m; ++i) 124 { 125 int u = get_i(); 126 int v = get_i(); 127 int f = get_i(); 128 int w = get_i(); 129 add(u, v, f, w); 130 } 131 132 s = n, t = n - 1; 133 134 add(s, 0, flow, 0); 135 136 printf("%d ", mcmf()); 137 }
@Author: YouSiki