网络流:最大流之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\n",ans);
96    }
97    return 0;   
98 }

猜你喜欢

转载自www.cnblogs.com/St-Lovaer/p/11909174.html