网络流 dinic算法

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 #define pb push_back
  8 
  9 const int N = 1e4 + 10;
 10 const int M = 1e5 + 10;
 11 const int INF = 2e9;
 12 struct edge{
 13     int to, nxt, flow;
 14 }e[M << 1];
 15 int head[N], d[N], cur[N];
 16 queue<int > que;
 17 int n, m, s, t, tot;
 18 
 19 //dinic算法 复杂度O(n^2*m) 二部图时O(n^0.5*m)
 20 //bfs分层  增广路只能从上一层走到下一层
 21 //dfs求流  得到该增广路的最小允许流
 22 
 23 inline void add(int u, int v, int flow){
 24     e[tot].to = v; e[tot].flow = flow;
 25     e[tot].nxt = head[u]; head[u] = tot++;
 26     e[tot].to = u; e[tot].flow = 0;
 27     e[tot].nxt = head[v]; head[v] = tot++;
 28 }
 29 
 30 inline void init(){
 31     for(int i = 1; i <= n; ++i) cur[i] = head[i];
 32     while(!que.empty()) que.pop();
 33     for(int i = 1; i <= n; ++i) d[i] = 0;
 34 }
 35 
 36 bool bfs(int s, int t){
 37     d[s] = 1;
 38     que.push(s);
 39     int to, flow;
 40     while(!que.empty()){
 41         int now = que.front();
 42         que.pop();
 43         for(int o = head[now]; ~o; o = e[o].nxt){
 44             to = e[o].to;
 45             flow = e[o].flow;
 46             if(!d[to] && flow){
 47                 d[to] = d[now] + 1;
 48                 que.push(to);
 49             }
 50         }
 51     }
 52     if(d[t]) return true;
 53     else return false;
 54 }
 55 
 56 int dfs(int now, int t, int F){
 57     if(now == t) return F;
 58 
 59     int sum = 0;
 60     int to, flow, tmp;
 61     //当前弧优化,因为是dfs,如果遍历了当前边,当它使用之后,之后再用到这个边很大概率效果也是和之前一样,减少了一些时间开销
 62     for(int& o = cur[now]; ~o; o = e[o].nxt){
 63         to = e[o].to;
 64         flow = e[o].flow;
 65         if(flow && d[to] == d[now] + 1){
 66             tmp = dfs(to, t, min(F - sum, flow));
 67             e[o].flow -= tmp; e[o^1].flow += tmp;
 68             sum += tmp;
 69             if(sum == F) return sum;
 70         }
 71     }
 72 
 73     return sum;
 74 }
 75 
 76 void dinic(int s,int& sum_flow){
 77     while(bfs(s, t)){
 78         sum_flow += dfs(s, t, INF);
 79         init();
 80     }
 81 }
 82 
 83 void solve(){
 84     
 85     while(~scanf("%d%d%d%d", &n, &m, &s, &t)){
 86         int u, v, w;
 87         for(int i = 1; i <= n; ++i) head[i] = -1; tot = 0;
 88         for(int i = 1; i <= m; ++i){
 89             scanf("%d%d%d", &u, &v, &w);
 90             add(u, v, w);
 91         }
 92         int sum_flow = 0;
 93         dinic(s, sum_flow);
 94         //printf("sum_flow = %d\n", sum_flow);
 95         printf("%d\n", sum_flow);
 96     }
 97 }
 98 
 99 int main(){
100 
101     solve();
102 
103     return 0;
104 }

 

上一篇:浅谈网络流Dinic算法


下一篇:网络流的最大流入门(从普通算法到dinic优化)