poj 1273 Drainage Ditches (网络流 最大流)

题目链接:

  http://poj.org/problem?id=1273

题目大意:

  n条边,m个点,每条边都有一个最大流量,问,源点1到汇点m的最大流?

解题思路:

  模板网络流,要注意的是会有重边。(~_~很小白,模板网络流,但是我还是想发博,毕竟第一道网络流嘛,也算是丰富博客内容。。。。。)

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <iostream>
  6 #include <cmath>
  7 #include <queue>
  8 using namespace std;
  9 
 10 #define maxn 0x3f3f3f3f
 11 #define N 210
 12 int map[N][N], Layer[N], n, m;
 13 bool visit[N];
 14 
 15 bool CountLayer ();
 16 int Dinic ();
 17 int main ()
 18 {
 19     while (scanf ("%d %d", &n, &m) != EOF)
 20     {
 21         int s, e, v;
 22         memset (map, 0, sizeof(map));
 23         for (int i=0; i<n; i++)
 24             {
 25                 scanf ("%d %d %d", &s, &e, &v);
 26                 map[s][e] += v;//会出现重复边
 27             }
 28         printf ("%d\n", Dinic());
 29     }
 30     return 0;
 31 }
 32 
 33 bool CountLayer ()
 34 {//给残余网络分层
 35     deque <int> Q;
 36     memset (Layer, -1, sizeof(Layer));//初始化层编号为-1
 37     Layer[1] = 1;//初始化源点
 38     Q.push_back(1);//源点进队
 39     while (!Q.empty())
 40     {
 41         int nd = Q.front();
 42         Q.pop_front();
 43         for (int i=1; i<=m; i++)
 44         {
 45             if (map[nd][i] > 0 && Layer[i] == -1)
 46             {
 47                 Layer[i] = Layer[nd] + 1;
 48                 if (i == m)//分层到汇点就可以停止了
 49                     return true;
 50                 else
 51                     Q.push_back(i);
 52             }
 53         }
 54     }
 55     return false;
 56 }
 57 int Dinic ()
 58 {
 59     int  maxnflow = 0;
 60     while (CountLayer())
 61     {//能够分层成功就存在增广路
 62         deque <int> Q;//dfs队列
 63         memset (visit, 0, sizeof(visit));
 64         visit[1] = 1;//源点入队
 65         Q.push_back(1);
 66         while (!Q.empty())
 67         {
 68             int nd = Q.back(), i;
 69             if (nd != m)
 70             {
 71                 for (i=1; i<=m; i++)
 72                 {
 73                     if (map[nd][i] > 0 && Layer[nd] + 1 == Layer[i] && !visit[i])
 74                     {//dfs下一层,没有走过的节点
 75                         visit[i] = 1;
 76                         Q.push_back(i);
 77                         break;
 78                     }
 79                 }
 80                 if (i > m)//在下一层里找不到点,退出本层点,以便继续dfs
 81                     Q.pop_back();
 82             }
 83             else//末点是汇点,则找到一条增广路经
 84             {
 85                 int mflow = maxn;//增广流量
 86                 int mv;//最小容量边的起点
 87                 for (i=1; i<Q.size(); i++)
 88                 {//遍历经过的边,路径上容量最小的边,就是增广流量
 89                     int ns, ne;
 90                     ns = Q[i-1];
 91                     ne = Q[i];
 92                     if (map[ns][ne] < mflow)
 93                     {
 94                         mflow = map[ns][ne];
 95                         mv = ns;
 96                     }
 97                 }
 98                 maxnflow += mflow;//增广,改图
 99                 for (i=1; i<Q.size(); i++)
100                 {
101                     int ns, ne;
102                     ns = Q[i-1];
103                     ne = Q[i];
104                     map[ns][ne] -= mflow;//修改边容量
105                     map[ne][ns] += mflow;//增加反向边
106                 }
107                 while (!Q.empty() && Q.back() != mv)
108                     Q.pop_back();//出队,以便增广下一条路径
109             }
110         }
111     }
112     return maxnflow;
113 }

 

posted @ 2015-04-30 11:07  罗茜  阅读(157)  评论(0编辑  收藏  举报