zoukankan      html  css  js  c++  java
  • 网络流:最大流之Dinic算法

    网络流主要解决三种问题:最大流、最小流和费用流。

    最大流算法主要有三种:EK算法、Dinic算法、SAP算法。

    本篇博客是关于Dinic算法的。最坏的情况下,Dinic算法将达到复杂度O(V2E)。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <cstring>
     6  
     7 using namespace std;
     8 const int INF = 0x3f3f3f3f;
     9 const int maxn = 200 + 10;
    10 const int maxm = 200 + 10;
    11  
    12 int n,m;
    13 int l[maxn];//记录层数
    14 int h[maxn];//链式前向星
    15 int cur[maxn];
    16 int tot = 0;
    17  
    18 struct edge
    19 {
    20   int to;
    21   int c;
    22   int next;
    23   edge(int x = 0, int y = 0, int z = 0) : to(x), c(y), next(z) {}
    24  }es[maxm*2];//记录边 注意是2倍
    25  
    26 void add_edge(int u, int v, int c)
    27 {
    28     es[tot] = edge(v,c,h[u]);
    29     h[u] = tot++;
    30 }
    31  
    32 bool bfs(int s, int t)
    33 {
    34    memset(l,0,sizeof(l));
    35    l[s] = 1;
    36    queue <int> q;
    37    q.push(s);
    38    while(!q.empty())
    39    {
    40     int u = q.front();
    41     q.pop();
    42     if(u == t)  return true;
    43     for(int i = h[u]; i != -1; i = es[i].next)
    44         {
    45          int v = es[i].to;
    46          if(!l[v] && es[i].c) {l[v] = l[u] + 1; q.push(v);}
    47         }
    48    }
    49    return false;
    50 }
    51  
    52 int dfs(int x, int t, int mf)
    53 {
    54     if(x == t) return mf;
    55     int ret = 0;
    56     for(int i = cur[x]; i != -1; i = es[i].next)
    57     {
    58       if(es[i].c && l[x] == l[es[i].to] - 1)
    59       {
    60         int f = dfs(es[i].to,t,min(es[i].c,mf - ret));
    61         es[i].c -= f;
    62         es[i^1].c += f;
    63         ret += f;
    64         if(ret == mf) return ret;
    65       }
    66     }
    67     return ret;
    68 }
    69  
    70 int dinic(int s, int t)
    71 {
    72   int ans = 0;
    73   while(bfs(s,t))
    74   {
    75    for(int i = 0; i <= n; i++) cur[i] = h[i];
    76    ans += dfs(s,t,INF);
    77    }
    78   return ans;
    79 }
    80  
    81 int main()
    82 {
    83    while(~scanf("%d%d",&n,&m))
    84    {
    85    tot = 0;
    86    memset(h,-1,sizeof(h));
    87    int u,v,c;
    88    for(int i = 0; i < m; i++)
    89    {
    90     scanf("%d%d%d",&u,&v,&c);
    91     add_edge(u,v,c);
    92     add_edge(v,u,0);//增加反向边
    93    }
    94    int ans = dinic(1,n);
    95    printf("%d
    ",ans);
    96    }
    97    return 0;   
    98 }
  • 相关阅读:
    理性与感性
    JVM系列(之class文件)
    Java集合框架
    Java字符串连接的几种方式
    JVM系列(之ClassLoader)
    时之终结
    约束中的存在
    拿什么爱你?我的数学
    梦的表征、抽象的思维
    Spider with R
  • 原文地址:https://www.cnblogs.com/St-Lovaer/p/11909174.html
Copyright © 2011-2022 走看看