身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了。
A flow network is a directed graph which has a 




 and a
 and a 


 . In a flow network, each edge
. In a flow network, each edge 



 has a capacity
has a capacity 




 . Each edge receives a flow, but the amount of flow on the edge can not exceed the corresponding capacity. Find the maximum flow from the
. Each edge receives a flow, but the amount of flow on the edge can not exceed the corresponding capacity. Find the maximum flow from the 




 to the
 to the 


 .
.
A flow network is given in the following format.






































 ,
, 

 is the number of vertices and edges of the flow network respectively. The vertices in
 is the number of vertices and edges of the flow network respectively. The vertices in  are named with the numbers 0, 1,...,
 are named with the numbers 0, 1,..., 



 . The source is 0 and the sink is
. The source is 0 and the sink is 



 .
.

 ,
, 
 ,
, 
 represent
 represent  -th edge of the flow network. A pair of
-th edge of the flow network. A pair of 
 and
 and 
 denotes that there is an edge from
 denotes that there is an edge from 
 to
to 
 and
 and 
 is the capacity of
 is the capacity of  -th edge.
-th edge.
Print the maximum flow.





























4 5 0 1 2 0 2 1 1 2 1 1 3 1 2 3 2
3
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\n", dinic()); 134 }
各辺にコストが設定されたフローネットワークにおいて、始点 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行に出力する。
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\n", mcmf()); 137 }
@Author: YouSiki
原文:http://www.cnblogs.com/yousiki/p/6227524.html