zoukankan      html  css  js  c++  java
  • 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
    ", 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    亚马逊EMR学习网站
    python实现redis三种cas事务操作
    【转】Jython简单入门
    【转】Android 收集已发布程序的崩溃信息
    【转】Android 避免APP启动闪黑屏(Theme和Style)
    【转】Android内存机制分析2——分析APP内存使用情况
    【转】Android内存机制分析1——了解Android堆和栈
    【转】JAVA Socket用法详解
    【转】JAVA 网络编程
    Android 无法Bind Service
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4468356.html
Copyright © 2011-2022 走看看