• 网络流-最大流ISAP


    之前学了ek和dinic,虽然dinic可以解决一般的最大流问题,但是有时候会被卡,所以我们考虑使用更快的ISAP算法

    改变

    ISAP和dinic一样使用分层标号来规定Dfs的进行方向。但是ISAP进行的是从终点反向标号,这样每次增广到一个点直接提升它的标号即可,把多次Bfs变成了一次Bfs,节省时间

    优化

    断层优化。当增广过程中全图出现了断层,即一个高度上没有任何节点,那么可以直接停止程序进行

    代码实现

      1 #include <cstdio>
      2 #include <queue>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using std::queue;
      7 using std::min;
      8 using std::max;
      9 
     10 const int MAXN = 1e4 + 5;
     11 const int INF = 0x3f3f3f3f;
     12 
     13 int n, m, s, t;
     14 
     15 struct Edge{
     16     int to, val;
     17     Edge *next, *opps;
     18     Edge(int to, int val, Edge *next):to(to), val(val), next(next){opps = NULL;}
     19 };
     20 
     21 Edge *head[MAXN];
     22 
     23 void AddEdge(int u, int v, int w) {
     24     head[u] = new Edge(v, w, head[u]);
     25     head[v] = new Edge(u, 0, head[v]);
     26     head[u]->opps = head[v]; head[v]->opps = head[u];
     27 }
     28 
     29 namespace ISAP{
     30     int gap[MAXN], dep[MAXN], maxflow = 0;
     31     Edge *cur[MAXN];
     32 
     33     void Bfs(int t) {
     34         memset(dep, -1, sizeof(dep));
     35         memset(gap, 0, sizeof(gap));
     36         queue <int> q;
     37         dep[t] = 0; gap[0] = 1;
     38         q.push(t);
     39         while (!q.empty()) {
     40             int u = q.front(); q.pop();
     41             for (Edge *e = head[u]; e; e = e->next) {
     42                 int v = e->to;
     43                 if (dep[v] != -1) continue;
     44                 q.push(v);
     45                 dep[v] = dep[u] + 1;
     46                 gap[dep[v]]++;
     47             }
     48         }
     49     }
     50 
     51     int Dfs(int u, int flow) {
     52         if (u == t) {
     53             maxflow += flow;
     54             return flow;
     55         }
     56         int used = 0;
     57         for (Edge *&e = cur[u]; e; e = e->next) {
     58             int v = e->to;
     59             if (e->val && dep[v] == dep[u] - 1) {
     60                 int mi = Dfs(v, min(e->val, flow - used));
     61                 if (mi) {
     62                     used += mi;
     63                     e->val -= mi;
     64                     e->opps->val += mi;
     65                 }
     66                 if (used == flow) return used;
     67             }
     68         }
     69         --gap[dep[u]];
     70         if (gap[dep[u]] == 0) dep[s] = n + 1;
     71         cur[u] = head[u];
     72         dep[u]++;
     73         ++gap[dep[u]];
     74         return used;
     75     }
     76 
     77     void Work(int s, int t) {
     78         maxflow = 0;
     79         memcpy(cur, head, sizeof(head));
     80         Bfs(t);
     81         while (dep[s] < n) Dfs(s, INF);
     82     }
     83 }
     84 
     85 void Pre() {
     86     scanf("%d %d %d %d", &n, &m, &s, &t);
     87     memset(head, 0, sizeof(head));
     88     int x, y, z;
     89     for (int i = 1; i <= m; i++) {
     90         scanf("%d %d %d", &x, &y, &z);
     91         AddEdge(x, y, z);
     92     }
     93 }
     94 
     95 int main() {
     96     Pre();
     97     ISAP::Work(s, t);
     98     printf("%d
    ", ISAP::maxflow);
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    VS 2005 RDLC报表实现WEB客户端打印(2)
    VS 2005 RDLC报表实现WEB客户端打印(1)
    封装就是一个包装,将包装的内外分为两个空间
    以count或是sum为条件的查询
    DbRulesAuthorizationProvider for .net 2.0
    Asp.net Ajax 'Sys'未定义
    广州网球场地名录
    谷歌 寄语
    深圳市网球场地一览表
    .net 2.0 串口通讯一小例
  • 原文地址:https://www.cnblogs.com/Juruo1103/p/10500163.html
Copyright © 2020-2023  润新知