zoukankan      html  css  js  c++  java
  • dinic

    本人很懒,半年前看的DINIC算法,也明白了其中的原理,但一直没有尝试。今天第一次,参照了其他人的模版。

    DINIC优缺点:最大流算法,时间N*N*M,非递归算法更好理解,也更快,但是代码更长!

    DINIC思想:通过广搜给每的个结点分层,通过深搜给找一条可以流到终点的流(只搜深度大1的点),统计这条流上的最小边(剩余的可行流)和这条边的起点,流上的最条边减最小边的权,反边加最小边的权,再从第一个最小边的起点再进行深搜(快的重要原因)。直到无法分层。

    题目:codevs1993

    题目描述 Description

    在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。

    农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。

    根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。

    输入描述 Input Description

    第1行: 两个用空格分开的整数N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。

    第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是这条排水沟的最大容量。

    输出描述 Output Description

    输出一个整数,即排水的最大流量。

    样例输入 Sample Input
    5 4
    1 2 40
    1 4 20
    2 4 20
    2 3 30
    3 4 10
    样例输出 Sample Output

    50

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<queue>
      5 #include<vector>
      6 
      7 using namespace std;
      8 const int inf=0x7fffffff;
      9 int n,m;
     10 int map[205][205]={0};
     11 int lays[205];
     12 bool vis[205];
     13 bool bfs()
     14 {
     15     queue<int>q;
     16     memset(lays,-1,sizeof(lays));
     17     lays[1]=0;
     18     q.push(1);
     19     while(!q.empty())
     20     {
     21         int u=q.front();
     22         q.pop();
     23         for(int i=1;i<=m;i++)
     24         {
     25             if(map[u][i]>0&&lays[i]==-1)
     26             {
     27                 lays[i]=lays[u]+1;
     28                 if(i==m)return 1;
     29                 else q.push(i);
     30             }
     31         }
     32     }
     33     return 0;
     34 }
     35 int dinic()
     36 {
     37     int maxf=0;
     38     vector <int> q;
     39     while(bfs())
     40     {
     41         q.push_back(1);
     42         memset(vis,0,sizeof(vis));
     43         vis[1]=1;
     44         while(!q.empty())
     45         {
     46             int nd=q.back();
     47             if(nd==m)
     48             {
     49                 int minn,minx=inf;
     50                 for(int i=1;i<q.size();i++)
     51                 {
     52                     int u=q[i-1],v=q[i];
     53                     if(map[u][v]>0&&map[u][v]<minx)
     54                     {
     55                         minx=map[u][v];
     56                         minn=u;
     57                     }
     58                 }
     59                 maxf+=minx;
     60                 for(int i=1;i<q.size();i++)
     61                 {
     62                     int u=q[i-1],v=q[i];
     63                     map[u][v]-=minx;
     64                     map[v][u]+=minx;
     65                 }
     66                 while(!q.empty()&&q.back()!=minn)
     67                 {
     68                     vis[q.back()]=0;
     69                     q.pop_back();
     70                 }
     71             }
     72             else
     73             {
     74                 int i;
     75                 for(i=1;i<=m;i++)
     76                 {
     77                     if(map[nd][i]>0&&lays[i]==lays[nd]+1&&!vis[i])
     78                     {
     79                         vis[i]=1;
     80                         q.push_back(i);
     81                         break;
     82                     }
     83                 }
     84                 if(i>m)q.pop_back();
     85             }
     86         }
     87     }
     88     return maxf;
     89 }
     90 int main()
     91 {
     92     cin>>n>>m;
     93     for(int i=0;i<n;i++)
     94     {
     95         int a,b,c;
     96         scanf("%d%d%d",&a,&b,&c);
     97         map[a][b]+=c;
     98     }
     99     cout<<dinic()<<endl;
    100     return 0;
    101 }
  • 相关阅读:
    面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字
    位运算技巧3
    Android消息循环分析
    ubuntu安装软件的方式
    fragment Trying to instantiate a class com.example.testhuanxindemo.MyFragment that is not a Fragmen
    LAN路由
    php 简易验证码(GD库)
    飘逸的python
    它们,不能是虚函数!!!
    HTML5调用摄像头实现拍照功能(兼容各大主流浏览器)
  • 原文地址:https://www.cnblogs.com/gryzy/p/5826790.html
Copyright © 2011-2022 走看看