首页 > 其他 > 详细

POJ_1273 Drainage Ditches 【网络流】

时间:2019-08-08 15:59:40      阅读:84      评论:0      收藏:0      [点我收藏+]

一、题面

  Drainage Ditches

二、分析

  网络流的裸题。

  1 Edmonds-Karp算法

    求解网络流其实就是一个不断找增广路,然后每次找到一条增广路后更新残余网络的一个过程。

    EK算法主要就是用bfs去找增广路,然后不断更新残余网络得到最终答案。

  2 Dinic算法

    对于Ford-Fulkerson和Edmonds-Karp算法,求解网络流都是一次次用DFS或者BFS,这其实是很费时的,Dinic相当于就是一次BFS然后DFS求解出多条增广路。

三、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 }

 

POJ_1273 Drainage Ditches 【网络流】

原文:https://www.cnblogs.com/dybala21/p/11318456.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!