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

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

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

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

      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 head[maxn];//链式前向星
     14     int tot = 0;
     15  
     16     struct edge
     17     {
     18       int to;
     19       int c;
     20       int next;
     21       edge(int x = 0, int y = 0, int z = 0) : to(x), c(y), next(z) {}
     22      }es[maxm*2];//记录边 注意是2倍
     23  
     24     void add_edge(int u, int v, int c)
     25     {
     26         es[tot] = edge(v,c,head[u]);
     27         head[u] = tot++;
     28     }
     29  
     30  
     31     int SAP(int s, int t)
     32     {
     33         int numh[maxn],h[maxn],ce[maxn],pre[maxn];
     34         //numh 记录gap优化的统计高度数量数组,h 距离标号数组,ce 当前弧,pre前驱数组
     35         int f, ans = 0, u, temp, neck, i; //初始化最大流为0
     36         memset(h,0,sizeof(h));
     37         memset(numh,0,sizeof(numh));
     38         memset(pre,-1,sizeof(pre));
     39         for(i = 1; i <= n; i++)  ce[i] = head[i];
     40         numh[0] = n;
     41         u = s;
     42         while(h[s] < n)
     43         {
     44             //寻找增广路
     45             if(u == t)
     46             {
     47                 f = INF;
     48                 for(i = s; i != t; i = es[ce[i]].to)
     49                 {
     50                     if(f > es[ce[i]].c)
     51                     {
     52                         neck = i;
     53                         f = es[ce[i]].c;
     54                     }
     55                 }
     56                 for(i = s; i != t; i = es[ce[i]].to)
     57                 {
     58                     temp = ce[i];
     59                     es[temp].c -= f;
     60                     es[temp^1].c += f;
     61                 }
     62                 ans += f;
     63                 u = neck;
     64             }
     65  
     66             //寻找可行弧
     67             for(i = ce[u]; i != -1; i = es[i].next)
     68                 if(es[i].c && h[u] == h[es[i].to] + 1)  break;
     69  
     70            //寻找增广路
     71             if(i != -1)
     72             {
     73                 ce[u] = i;
     74                 pre[es[i].to] = u;
     75                 u = es[i].to;
     76             }
     77             else
     78             {
     79                 if(!--numh[h[u]]) break; //gap optimization
     80                 ce[u] = head[u];
     81                 for(temp = n, i = head[u]; i != -1; i = es[i].next)
     82                     if(es[i].c)  temp = min(temp, h[es[i].to]);
     83  
     84                 h[u] = temp + 1;
     85                 ++numh[h[u]];
     86                 if(u != s) u = pre[u];//重标号并且从当前点前驱重新增广
     87             }
     88  
     89         }
     90         return ans;
     91     }
     92  
     93     int main()
     94     {
     95        while(~scanf("%d%d",&n,&m))
     96        {
     97        tot = 0;
     98        memset(head,-1,sizeof(head));
     99        int u,v,c;
    100        for(int i = 0; i < m; i++)
    101        {
    102         scanf("%d%d%d",&u,&v,&c);
    103         add_edge(u,v,c);
    104         add_edge(v,u,0);//增加反向边
    105        }
    106        int ans = SAP(1,n);
    107        printf("%d
    ",ans);
    108        }
    109        return 0;   
    110     }
  • 相关阅读:
    HDU 2196 Computer
    HDU 1520 Anniversary party
    POJ 1217 FOUR QUARTERS
    POJ 2184 Cow Exhibition
    HDU 2639 Bone Collector II
    POJ 3181 Dollar Dayz
    POJ 1787 Charlie's Change
    POJ 2063 Investment
    HDU 1114 Piggy-Bank
    Lca hdu 2874 Connections between cities
  • 原文地址:https://www.cnblogs.com/St-Lovaer/p/11909244.html
Copyright © 2011-2022 走看看