• 最大流、最小割模板


    Dinic 模板

     1 struct Edge {
     2     int from, to, cap, flow;
     3 };
     4 struct Dinic {
     5     int n, m, s, t;
     6     vector<Edge>edges;
     7     vector<int>G[MAXN];
     8     bool vis[MAXN];
     9     int d[MAXN];
    10     int cur[MAXN];
    11     void init(int n) {
    12         for (int i = 0; i < MAXN; i++) G[i].clear();
    13         edges.clear();memset(d,0,sizeof(d));
    14     }
    15     void AddEdge(int from, int to, int cap) {
    16         edges.push_back({ from, to, cap, 0 });
    17         edges.push_back({ to, from, 0, 0 });
    18         m = edges.size();
    19         G[from].push_back(m - 2);
    20         G[to].push_back(m - 1);
    21     }
    22     bool BFS() {
    23         int x, i;
    24         memset(vis, 0, sizeof(vis));
    25         queue<int>Q;
    26         Q.push(s);
    27         d[s] = 0;
    28         vis[s] = 1;
    29         while (!Q.empty()) {
    30             x = Q.front(), Q.pop();
    31             for (i = 0; i < G[x].size(); i++) {
    32                 Edge & e = edges[G[x][i]];
    33                 if (!vis[e.to] && e.cap > e.flow) {
    34                     vis[e.to] = 1;
    35                     d[e.to] = d[x] + 1;
    36                     Q.push(e.to);
    37                 }
    38             }
    39         }
    40         return vis[t];
    41     }
    42     int DFS(int x, int a) {
    43         if (x == t || a == 0)
    44             return a;
    45         int flow = 0, f;
    46         for (int &i = cur[x]; i < G[x].size(); i++) {
    47             Edge & e = edges[G[x][i]];
    48             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
    49                 e.flow += f;
    50                 edges[G[x][i] ^ 1].flow -= f;
    51                 flow += f;
    52                 a -= f;
    53                 if (a == 0)
    54                     break;
    55             }
    56         }
    57         return flow;
    58     }
    59     int Maxflow(int s, int t) {
    60         this->s = s, this->t = t;
    61         int flow = 0;
    62         while (BFS()) {
    63             memset(cur, 0, sizeof(cur));
    64             flow += DFS(s, INF);
    65         }
    66         return flow;
    67     }
    68 };

    Edmonds Karp模板

     1 const int maxn=;
     2 const int inf=0x3f3f3f3f;
     3 struct Edge
     4 {
     5     int from,to,cap,flow;
     6     Edge(int u,int v,int c,int f): from(u),to(v),cap(c),flow(f) {}
     7 };
     8 
     9 struct EdmondsKarp
    10 {
    11     int n,m;
    12     vector<Edge> edges;
    13     vector<int> G[maxn];
    14     int a[maxn];
    15     int p[maxn];
    16 
    17     void init(int n)
    18     {
    19       for(int i=0;i<n;i++) G[i].clear();
    20       edges.clear();
    21     }
    22 
    23     void AddEdge(int from,int to,int cap)
    24     {
    25        edges.push_back(Edge(from,to,cap,0));
    26        edges.push_back(Edge(to,from,0,0));
    27        m=edges.size();
    28        G[from].push_back(m-2);
    29        G[to].push_back(m-1);
    30     }
    31 
    32    int Maxflow(int s,int t)
    33    {
    34      int flow=0;
    35      while(1)
    36      {
    37         memset(a,0,sizeof(a));
    38         queue<int> Q;
    39         Q.push(s);
    40         a[s]=inf;
    41         while(!Q.empty())
    42         {
    43             int x=Q.front();Q.pop();
    44             for(int i=0;i<G[x].size();i++)
    45             {
    46                 Edge& e=edges[G[x][i]];
    47                 if(!a[e.to]&&e.cap>e.flow)
    48                 {
    49                     p[e.to]=G[x][i];
    50                     a[e.to]=min(a[x],e.cap-e.flow);
    51                     Q.push(e.to);
    52                 }
    53             }
    54             if(a[t]) break;
    55         }
    56         if(!a[t]) break;
    57         for(int u=t;u!=s;u=edges[p[u]].from)
    58         {
    59             edges[p[u]].flow+=a[t];
    60             edges[p[u]^1].flow-=a[t];
    61         }
    62         flow+=a[t];
    63     }
    64     return flow;    
    65    }
    66 };

    对于最小割来说,在算法结束后,令已经标号的结点(a[u]>0的结点)集合为S,其他集合为T=V-S,则(S,T)是图 s-t 的最小割


    ISAP,附带Mincut方案

      1 #include<bits/stdc++.h>
      2 #define REP(i, a, b) for(int i = (a); i < (b); i++)
      3 #define MEM(a,x) memset(a,x,sizeof(a)) 
      4 #define INF 0x3f3f3f3f 
      5 #define MAXN 100000+10
      6 using namespace std;
      7 
      8 struct Edge
      9 {
     10     int from, to, cap, flow;
     11     Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {}
     12 };
     13 
     14 struct ISAP
     15 {
     16     int n, m, s, t;
     17     vector<Edge>edges;
     18     vector<int>G[MAXN];
     19     bool vis[MAXN];
     20     int d[MAXN], cur[MAXN];
     21     int p[MAXN], num[MAXN];//比Dinic算法多了这两个数组,p数组标记父亲结点,num数组标记距离d[i]存在几个
     22     void addedge(int from, int to, int cap)
     23     {
     24         edges.push_back(Edge(from, to, cap, 0));
     25         edges.push_back(Edge(to, from, 0, 0));
     26         int m = edges.size();
     27         G[from].push_back(m - 2);
     28         G[to].push_back(m - 1);
     29     }
     30 
     31     void init(int n) {
     32         this->n = n;
     33         for (int i = 0; i < n; i++) {
     34             G[i].clear();
     35         }
     36         edges.clear();
     37     }
     38 
     39     int Augumemt()
     40     {
     41         int x = t, a = INF;
     42         while (x != s)//找最小的残量值
     43         {
     44             Edge&e = edges[p[x]];
     45             a = min(a, e.cap - e.flow);
     46             x = edges[p[x]].from;
     47         }
     48         x = t;
     49         while (x != s)//增广
     50         {
     51             edges[p[x]].flow += a;
     52             edges[p[x] ^ 1].flow -= a;//更新反向边。
     53             x = edges[p[x]].from;
     54         }
     55         return a;
     56     }
     57     void BFS()//逆向进行bfs
     58     {
     59         memset(vis, 0, sizeof(vis));
     60         queue<int>q;
     61         q.push(t);
     62         d[t] = 0;
     63         vis[t] = 1;
     64         while (!q.empty())
     65         {
     66             int x = q.front(); q.pop();
     67             int len = G[x].size();
     68             for (int i = 0; i < len; i++)
     69             {
     70                 Edge&e = edges[G[x][i]];
     71                 if (!vis[e.from] && e.cap > e.flow)
     72                 {
     73                     vis[e.from] = 1;
     74                     d[e.from] = d[x] + 1;
     75                     q.push(e.from);
     76                 }
     77             }
     78         }
     79     }
     80 
     81     int Maxflow(int s, int t)//根据情况前进或者后退,走到汇点时增广
     82     {
     83         this->s = s;
     84         this->t = t;
     85         int flow = 0;
     86         BFS();
     87         memset(num, 0, sizeof(num));
     88         for (int i = 0; i < n; i++)
     89             num[d[i]]++;
     90         int x = s;
     91         memset(cur, 0, sizeof(cur));
     92         while (d[s] < n)
     93         {
     94             if (x == t)//走到了汇点,进行增广
     95             {
     96                 flow += Augumemt();
     97                 x = s;//增广后回到源点
     98             }
     99             int ok = 0;
    100             for (int i = cur[x]; i < G[x].size(); i++)
    101             {
    102                 Edge&e = edges[G[x][i]];
    103                 if (e.cap > e.flow&&d[x] == d[e.to] + 1)
    104                 {
    105                     ok = 1;
    106                     p[e.to] = G[x][i];//记录来的时候走的边,即父边
    107                     cur[x] = i;
    108                     x = e.to;//前进
    109                     break;
    110                 }
    111             }
    112             if (!ok)//走不动了,撤退
    113             {
    114                 int m = n - 1;//如果没有弧,那么m+1就是n,即d[i]=n
    115                 for (int i = 0; i < G[x].size(); i++)
    116                 {
    117                     Edge&e = edges[G[x][i]];
    118                     if (e.cap > e.flow)
    119                         m = min(m, d[e.to]);
    120                 }
    121                 if (--num[d[x]] == 0)break;//如果走不动了,且这个距离值原来只有一个,那么s-t不连通,这就是所谓的“gap优化”
    122                 num[d[x] = m + 1]++;
    123                 cur[x] = 0;
    124                 if (x != s)
    125                     x = edges[p[x]].from;//退一步,沿着父边返回
    126             }
    127         }
    128         return flow;
    129     }
    130     vector<int>Mincut() {
    131         BFS();
    132         vector<int>ans;
    133         for (int i = 0; i < edges.size(); i++) {
    134             Edge& e = edges[i];
    135             if (!vis[e.from] && vis[e.to] && e.cap > 0)
    136                 ans.push_back(i);
    137         }
    138         return ans;
    139     }
    140 };
  • 相关阅读:
    查找算法(I) 顺序查找 二分查找 索引查找
    快速排序 Quick Sort
    Activity生命周期
    Android中资源文件的使用
    排序算法
    插入排序(I)Insert Sort
    Java eclipse调试技巧什么的。。
    HTTP协议解析
    python技巧26[str+unicode+codecs]
    python类库26[PySide之helloworld]
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9567387.html
Copyright © 2020-2023  润新知