Drainage Ditches 最大流入门练习题,各种算法

                          Drainage Ditches

题目抽象:n个顶点,m条容量为ci的边组成的图,求源点为1,汇点为n的最大流。

分析:各种最大流算法。

1.ford()

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstring>
 5 using namespace std;
 6 const int INF = 0x5fffffff;
 7 const int MS = 205;
 8
 9 struct edge {
10     int c, f;
11 };
12
13 edge edges[MS][MS];
14 int flag[MS];
15 int pre[MS];
16 int alpha[MS];
17 int n, m, s, t;
18 int que[MS];  // QUEUE
19
20 int ford() {
21     while (1) {
22         memset(flag, -1, sizeof(flag));
23         memset(pre, -1, sizeof(pre));
24         memset(alpha, -1, sizeof(alpha));
25         flag[1] = 0;
26         pre[1] = 0;
27         alpha[1] = INF;
28         s = t = 0;
29         que[t++] = 1;
30         while (s < t && flag[n] == -1) {
31             int u = que[s++];
32             for (int v = 1; v <= n; v++) {
33                 if (flag[v] == -1) {
34                     if (edges[u][v].c > 0 && edges[u][v].f < edges[u][v].c) {
35                         flag[v] = 0;
36                         pre[v] = u;
37                         alpha[v] = min(alpha[u], edges[u][v].c - edges[u][v].f);
38                         que[t++] = v;
39                     }
40                     else if (edges[v][u].c > 0 && edges[v][u].f > 0) {
41                         flag[v] = 0;
42                         pre[v] = -u;
43                         alpha[v] = min(alpha[u], edges[v][u].f);
44                         que[t++] = v;
45                     }
46                 }
47             }
48             flag[u] = 1;
49         }
50         if (flag[n] == -1 || alpha[n] == 0)
51             break;
52         int a = alpha[n];
53         int k1 = n;
54         int k2 = abs(pre[k1]);
55         while (1) {
56             if (edges[k2][k1].c > 0)
57                 edges[k2][k1].f += a;
58             else
59                 edges[k1][k2].f -= a;
60             if (k2 == 1)
61                 break;
62             k1 = k2;
63             k2 = abs(pre[k1]);
64         }
65     }
66     int maxFlow = 0;
67     for (int i = 1; i <= n; i++) {
68         for (int j = 1; j <= n; j++) {
69             if (i == 1 && edges[i][j].f > 0)
70                 maxFlow += edges[i][j].f;
71         }
72     }
73     return maxFlow;
74 }
75
76 int main() {
77     while (scanf("%d%d", &m, &n) != EOF) {
78         for (int i = 0; i <= n; i++) {
79             for (int j = 0; j <= n; j++) {
80                 edges[i][j].c = edges[i][j].f = 0;
81             }
82         }
83         int u, v, c;
84         for (int i = 0; i < m; i++) {
85             scanf("%d%d%d", &u, &v, &c);
86             edges[u][v].c += c;   //  如有有重边,+=
87         }
88         int maxFlow = ford();
89         printf("%d\n", maxFlow);
90     }
91     return 0;
92 }

2.dinic算法。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int INF = 0x5fffffff;
 6 const int MS = 205;
 7
 8 int edges[MS][MS];
 9 int level[MS];
10 int que[MS];
11 int n, m, s, t;
12
13 int BFS() {
14     memset(level, -1, sizeof(level));
15     level[1] = 0;
16     s = t = 0;
17     que[t++] = 1;
18     while (s < t) {
19         int u = que[s++];
20         for (int v = 1; v <= n; v++) {
21             if (level[v] < 0 && edges[u][v] > 0) {
22                 level[v] = level[u] + 1;
23                 que[t++] = v;
24             }
25         }
26     }
27     if (level[n] > 0)
28         return 1;
29     else
30         return 0;
31 }
32
33 int DFS(int u, int minv) {
34     if (u == n)
35         return minv;
36     int t;
37     for (int v = 1; v <= n; v++) {
38         if (edges[u][v] > 0 && level[v] == level[u] + 1 && (t = DFS(v, min(minv, edges[u][v])))) {
39             edges[u][v] -= t;
40             edges[v][u] += t;
41             return t;
42         }
43     }
44     return 0;
45 }
46
47 int main() {
48     while (scanf("%d%d", &m, &n) != EOF) {
49         memset(edges, 0, sizeof(edges));
50         int u, v, c;
51         for (int i = 0; i < m; i++) {
52             scanf("%d%d%d", &u, &v, &c);
53             edges[u][v] += c;
54         }
55         int ans = 0;
56         int t;
57         while (BFS()) {
58             while ((t = DFS(1, INF)))
59                 ans += t;
60         }
61         printf("%d\n", ans);
62     }
63     return 0;
64 }
时间: 2024-10-11 21:48:23

Drainage Ditches 最大流入门练习题,各种算法的相关文章

POJ 1273 Drainage Ditches (网络流最大流基础 Edmonds_Karp算法)

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 59219   Accepted: 22740 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

HDU-1532 Drainage Ditches (最大流,EK算法模板)

题目大意:最大流的模板题...源点是0,汇点是n-1. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<string> # include<vector> # include<list> # include<set> # include<map> # include<queue> # include<

Drainage Ditches(最大流基础_增广路算法)

 Drainage DitchesCrawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover p

XTU 二分图和网络流 练习题 J. Drainage Ditches

J. Drainage Ditches Time Limit: 1000ms Memory Limit: 32768KB 64-bit integer IO format: %I64d      Java class name: Main Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is cover

HDU 1532 Drainage Ditches 最大排水量 网络最大流 Edmonds_Karp算法

题目链接:HDU 1532 Drainage Ditches 最大排水量 Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9641    Accepted Submission(s): 4577 Problem Description Every time it rains on Farmer John

POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)

http://poj.org/problem?id=1273 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 Jo

POJ 1273 Drainage Ditches(我的EK算法模板)

题意:给你n条边,目标位置t:接下来是每条边,包括起点,终点,容量: 感想:第一道最大流的代码,这道题是我更深地理解了Ek算法,不过这道题有个超坑的情况,那就是出现重边的情况==! 思路:EK算法 AC代码: #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 100000000 #define N

POJ 1273 Drainage Ditches (最大流问题——Edmonds-Karp算法)

一.最大流问题 最大流问题最形象的比喻就是给定一个有向图G(V,E),每个边有一定的权值表示边的容量,再给定起点s和终点t,s处有水不断的流出,t是一个蓄水池,问最多有多少水从s流进了t? 二.Edmonds-Karp算法 简单来说这个算法就是不断重复这样的操作: 1.从图中找到s到t的路径(为了减小时间复杂度使用bfs来寻找最短的一条路径),如果找不到路径,那么就结束. 2.找到的该路径所有边容量的最小值,这是s通过这条路径到达t的最大值,称为nMinFlow 3.从这条路径的每一个边上的容量

POJ 1273 Drainage Ditches(初识网络流)

开始研究网络流了,看了两个晚上吧,今天总算动手实践一下,有了更深的理解 总结一下:在最大流中,容量与实际流量满足3点: 1.实际流量<=容量 2.任意两点之间   : 流量(a->b)==流量(b->a) 3.流量守恒原则   :从s流出的流量 == t流入的流量 一.为什么叫增广路,因为在所有的流量网络中,会存在一个残量,所以在整个残量网络中,找到一个最小值,加到所有的流量线路里,便叫增广. 二.为什么要修改反向流量,因为在更新流量网时,当前选择的并不一定就是最优解,比如u->v