POJ_1273 Drainage Ditches 【网络流】
一、题面
二、分析
网络流的裸题。
1 Edmonds-Karp算法
求解网络流其实就是一个不断找增广路,然后每次找到一条增广路后更新残余网络的一个过程。
EK算法主要就是用bfs去找增广路,然后不断更新残余网络得到最终答案。
2 Dinic算法
对于Ford-Fulkerson和Edmonds-Karp算法,求解网络流都是一次次用DFS或者BFS,这其实是很费时的,Dinic相当于就是一次BFS然后DFS求解出多条增广路。
3 ISAP
三、AC代码
1 //Edmonds-Karp
2 #include <cstdio>
3 #include <iostream>
4 #include <vector>
5 #include <queue>
6 #include <cstring>
7 using namespace std;
8 #define ll long long
9 const int maxn = 2e2 + 13;
10 const int INF = 1e8 + 1;
11 int N, M;
12 int Flow[maxn]; //找到的最小的容量
13 int Pre[maxn]; //记录父节点
14 struct edge
15 {
16 //终点、容量、反边
17 int to, cap, rev;
18 };
19 int G[maxn][maxn];
20 void add_edge(int from, int to, int cap)
21 {
22 G[from][to] += cap;
23 }
24
25 int BFS(int s, int t)
26 {
27 memset(Pre, -1, sizeof(Pre));
28 queue<int> Q;
29 Q.push(s);
30 Pre[s] = -1;
31 Flow[s] = INF;
32 while(!Q.empty())
33 {
34 int q = Q.front();
35 if(q == t)
36 break;
37 Q.pop();
38 for(int i = 1; i <= M; i++)
39 {
40 if(i != s && G[q][i] > 0 && Pre[i] == -1)
41 {
42 Pre[i] = q;
43 Flow[i] = min(Flow[q], G[q][i]);
44 Q.push(i);
45 }
46 }
47 }
48 if(Pre[t] == -1)
49 return 0;
50 else
51 return Flow[t];
52 }
53
54 ll EK(int s, int t)
55 {
56 ll ans = 0;
57 int f = BFS(s, t);
58 while(f)
59 {
60 ans += f;
61 int p = t;
62 while(Pre[p] != -1)
63 {
64 G[Pre[p]][p] -= f;
65 G[p][Pre[p]] += f;
66 p = Pre[p];
67 }
68 f = BFS(s, t);
69 }
70 return ans;
71 }
72
73 int main()
74 {
75 freopen("input.txt", "r", stdin);
76 while(scanf("%d%d", &N, &M) != EOF)
77 {
78 memset(G, 0, sizeof(G));
79 int from, to, cap;
80 for(int i = 0; i < N; i++)
81 {
82 scanf("%d%d%d", &from, &to, &cap);
83 add_edge(from, to, cap);
84 }
85 printf("%I64d\n", EK(1, M));
86 }
87 return 0;
88 }
1 //Dinic
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #include <vector>
7 #include <queue>
8
9 using namespace std;
10 #define ll long long
11 #define Min(a,b) ((a)>(b)?(b):(a))
12 #define Max(a,b) ((a)>(b)?(a):(b))
13 const int INF = 1e9;
14 const int maxn = 5e2 + 13;
15 struct edge
16 {
17 int to, cap, rev;
18 };
19 vector<edge> G[maxn];
20 int N, M;
21 int level[maxn], iter[maxn];
22 //iter数组的作用就是记录DFS时该结点已经访问到的邻接点的位置
23 void add_edge(int from, int to, int cap)
24 {
25 G[from].push_back( (edge){to, cap, G[to].size()});
26 G[to].push_back( (edge){from, 0, G[from].size() - 1});
27 }
28
29 void BFS(int s)
30 {
31 memset(level, -1, sizeof(level));
32 queue<int> que;
33 level[s] = 0;
34 que.push(s);
35 while(!que.empty())
36 {
37 int v = que.front();
38 que.pop();
39 for(int i = 0; i < G[v].size(); i++)
40 {
41 edge &e = G[v][i];
42 if(e.cap > 0 && level[e.to] < 0)
43 {
44 level[e.to] = level[v] + 1;
45 que.push(e.to);
46 }
47 }
48 }
49 }
50
51 int DFS(int s, int t, int f)
52 {
53 if(s == t)
54 return f;
55 for(int &i = iter[s]; i < G[s].size(); i++)
56 {
57 edge &e = G[s][i];
58 if(e.cap > 0 && level[s] < level[e.to])
59 {
60 int d = DFS(e.to, t, Min(f, e.cap));
61 if(d > 0)
62 {
63 e.cap -= d;
64 G[e.to][e.rev].cap += d;
65 return d;
66 }
67 }
68 }
69 return 0;
70 }
71
72 int Dinic(int s, int t)
73 {
74 int flow = 0;
75 while(1)
76 {
77 BFS(s);
78 if(level[t] < 0)
79 return flow;
80 memset(iter, 0, sizeof(iter));
81 int f = DFS(s, t, INF);
82 while(f > 0)
83 {
84 flow += f;
85 f = DFS(s, t, INF);
86 }
87 }
88 }
89
90 int main()
91 {
92 //freopen("input.txt", "r", stdin);
93 int from, to, cap;
94 while(~scanf("%d%d", &N, &M))
95 {
96 for(int i = 0; i < N; i++)
97 {
98 scanf("%d%d%d", &from, &to, &cap);
99 add_edge(from, to, cap);
100 }
101 printf("%d\n", Dinic(1, M));
102 for(int i = 1; i < M; i++)
103 {
104 G[i].clear();
105 }
106 }
107 return 0;
108 }
1 //ISAP
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #include <vector>
7 #include <queue>
8
9 using namespace std;
10 #define ll long long
11 #define Min(a,b) ((a)>(b)?(b):(a))
12 #define Max(a,b) ((a)>(b)?(a):(b))
13 const int INF = 1e9;
14 const int maxn = 2e2 + 13;
15 struct edge{
16 int v, w, nxt;
17 } e[maxn<<1];
18 int h[maxn], tot, n, m, gap[maxn], last[maxn], d[maxn],que[maxn], ql, qr;
19 vector<int> inv[maxn];
20
21 int read() {
22 int x=0,f=1;
23 char c=getchar();
24 for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
25 for (;isdigit(c);c=getchar()) x=x*10+c-'0';
26 return x*f;
27 }
28
29 void add(int u, int v, int w)
30 {
31 e[++tot] = (edge){v, w, h[u]};
32 h[u] = tot;
33 e[++tot] = (edge){u, 0, h[v]};
34 h[v] = tot;
35 }
36
37 void init(int s, int t)
38 {
39 memset(gap, 0, sizeof(gap));
40 memset(d, 0, sizeof(d));
41 ++gap[d[t] = 1];
42 for(int i = 1; i <= n; i++)
43 last[i] = h[i];
44 que[ql = qr = 1] = t;
45 while(ql <= qr)
46 {
47 int x = que[ql++];
48 for(int i = h[x], v = e[i].v;i; i = e[i].nxt, v = e[i].v)
49 {
50 if(!d[v])
51 {
52 ++gap[d[v] = d[x] + 1];
53 que[++qr] = v;
54 }
55 }
56 }
57 }
58
59 int aug(int x, int s, int t, int mi)
60 {
61 if(x == t)
62 return mi;
63 int flow = 0;
64 for(int &i = last[x], v = e[i].v;i;i = e[i].nxt, v = e[i].v)
65 {
66 if(d[x] == d[v] + 1)
67 {
68 int tmp = aug(v, s, t, min(mi, e[i].w));
69 flow += tmp;
70 mi -= tmp;
71 e[i].w -= tmp;
72 e[i^1].w += tmp;
73 if(!mi)
74 return flow;
75 }
76 }
77 if(!(--gap[d[x]]))
78 d[s] = n + 1;
79 ++gap[++d[x]];
80 last[x] = h[x];
81 return flow;
82 }
83
84 int maxflow(int s, int t)
85 {
86 init(s, t);
87 int ret = aug(s, s, t, INF);
88 while(d[s] <= n)
89 ret += aug(s, s, t, INF);
90 return ret;
91 }
92
93 int main()
94 {
95 freopen("input.txt", "r", stdin);
96 while(~scanf("%d%d", &m, &n))
97 {
98 tot = 1;
99 memset(h, 0, sizeof(h));
100 for(int i = 1; i <= n; i++)
101 inv[i].clear();
102 for(int i = 1; i <= m; i++)
103 {
104 int u = read();
105 int v = read();
106 int w = read();
107 add(u, v, w);
108 if(w)
109 inv[v].push_back(u);
110 }
111 int ans = maxflow(1, n);
112 printf("%d\n", ans);
113 }
114 return 0;
115 }
POJ_1273 Drainage Ditches 【网络流】的更多相关文章
- POJ 1273 Drainage Ditches (网络流Dinic模板)
Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover ...
- POJ 1273:Drainage Ditches 网络流模板题
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 63339 Accepted: 2443 ...
- HDU1532 Drainage Ditches 网络流EK算法
Drainage Ditches Problem Description Every time it rains on Farmer John's fields, a pond forms over ...
- USACO 4.2 Drainage Ditches(网络流模板题)
Drainage DitchesHal Burch Every time it rains on Farmer John's fields, a pond forms over Bessie's fa ...
- NYOJ 323 Drainage Ditches 网络流 FF 练手
Drainage Ditches 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Every time it rains on Farmer John's fields, ...
- POJ 1273 Drainage Ditches 网络流 FF
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 74480 Accepted: 2895 ...
- Drainage Ditches~网络流模板
Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover ...
- poj 1273 Drainage Ditches 网络流最大流基础
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 59176 Accepted: 2272 ...
- poj 1273 Drainage Ditches (网络流 最大流)
网络流模板题. ============================================================================================ ...
随机推荐
- 全局ID生成--雪花算法改进版
存在的问题 时间回拨问题:由于机器的时间是动态的调整的,有可能会出现时间跑到之前几毫秒,如果这个时候获取到了这种时间,则会出现数据重复 机器id分配及回收问题:目前机器id需要每台机器不一样,这样的方 ...
- redis持久化-AOF
1.aof文件写入与同步 2.aof重写 重写的目的是为了减小aof文件的体积,redis服务器可以创建一个新的aof文件来代替现有的aof文件,新文件不会有冗余的命令. BGREWRITEAOF:遍 ...
- SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解
题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[ ...
- Right in the Center (js string algorithm)
Right in the Center (js string algorithm) codewars https://www.codewars.com/kata/5f5da7a415fbdc0001a ...
- html template tag
html template tag const tagName = `emoji-element`; const template = document.createElement('template ...
- Android 获取apk的URL Schemes
1. 下载apk到你的PC上 2. 反向工程Android APK文件的工具 Apktool 3. 查看"AndroidManifest.xml"文件 See alse: http ...
- Dart: path库
path库pub地址 安装: dependencies: path: 使用: import 'dart:io'; import 'package:path/path.dart' as path; ma ...
- C++算法代码——阿克曼函数
题目来自: 题目描述 阿克曼( Ackmann) 函数 A(x, y) 中, x, y 定义域是非负整数, 函数值定义为: 输入 输入两个数,表示m和n. 两个数均不超过10. 输出 输出一个数,表示 ...
- re模块之简单计算器的实现
本节大纲: 表达式的输入及检查.格式化 怎么样进行匹配最里面的括号以及操作数的匹配 如何实现表达式的四则运算 完整代码展示 在我们学习re模块之后,通常的练习就是利用所学相关知识来写一个计算器 那么, ...
- linux系统忘记root的登录密码
参考链接:https://www.jb51.net/article/146541.htm 亲测有效 使用场景 linux管理员忘记root密码,需要进行找回操作. 注意事项:本文基于centos7环 ...