网络流模板 NetworkFlow

身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了。

Network Flow - Maximum Flow

Time Limit : 1 sec, Memory Limit : 65536 KB 
Japanese version is here

Maximum Flow

A flow network is a directed graph which has a  and a . In a flow network, each edge 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  to the .

Input

A flow network is given in the following format.




:

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

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

Output

Print the maximum flow.

Constraints

Sample Input 1

4 5
0 1 2
0 2 1
1 2 1
1 3 1
2 3 2

Sample Output 1

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 }

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\n", mcmf());
137 }

@Author: YouSiki

时间: 2024-10-16 22:43:00

网络流模板 NetworkFlow的相关文章

Kuangbin网络流模板

Kuangbin网络流模板. const int maxn=20010; const int maxm=200010; const double INF=1e20; const double eps=1e-8; struct Edge{ int to,next; double cap,flow; }edge[maxm],tmpG[maxm]; int n,tot,toth,totv; int head[maxn],tmph[maxn]; int gap[maxn],dep[maxn],cur[m

HDU 4280 Island Transport(网络流模板)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4280 Problem Description In the vast waters far far away, there are many islands. People are living on the islands, and all the transport among the islands relies

算法复习——网络流模板(ssoj)

题目: 题目描述 有 n(0<n<=1000)个点,m(0<m<=1000)条边,每条边有个流量 h(0<=h<35000),求从点 start 到点 end 的最大流. 输入格式 第一行:4 个整数,分别是 n,m,start,end .接下来有 m 行,每行四个三个整数 a,b,h,分别表示 a 到 b,流量为 h 的一条边. 输出格式 输出从点 start 到点 end 的最大流. 样例数据 1 输入 [复制] 7 14 1 7 1 2 5 1 3 6 1 4 5

hdu1532——Drainage Ditches(网络流模板)

Problem Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of d

上下界的网络流模板

上下界网络流问题对于每一条边.都有流量上下限的限制 而普通的网络流就只有上限限制 下面分别给出几种经典上下界网络流问题的模板 参考博文Ⅰ.参考博文Ⅱ 1.无源汇的上下界可行流 实际也就是能否找出一个循环流.使得每个点的流入总流量 == 流出总流量 对于原图的每一条边在网络流中容量应当为 (上界 - 下界) 而后计算每个点流入流量的下界总和记为 in .流出流量的下界总和记为 out 抽象出超级源汇 ss 与 tt 对于原图中的每一个点 如果 in - out > 0 则 ss 与这个点连边.容量

Drainage Ditches--hdu1532(网络流 模板)

http://acm.hdu.edu.cn/showproblem.php?pid=1532 Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13790    Accepted Submission(s): 6527 Problem Description Every time it rains on F

HDU 3549 Flow Problem(网络流模板题)

记录一下模板 #include <vector> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> using namespace std; #define maxn 1100 #define INF 0x7f7f7f7f struct Edge { int from,to,cap,flow; }; struct Dinic { int n,m,s

Drainage Ditches - poj 1273(网络流模板)

题意:1是源点,m是汇点,求出来最大流量,没什么好说的就是练习最大流的模板题 ************************************************************** 先用Edmonds-Karp的算法做一下试试吧 重边贡献了 1W,要加上所有的重边才算是两点间最大流量 ************************************************************************* /*********************

POJ 1273 Drainage Ditches(网络流模板)

Description: Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage