SCL--最大流

2015-04-08 17:52:08

最大流小结:

  最大流的算法学了已经有一段时间了,题目也做了一些。是时候总结一个经常用的模板了。

(1)首先是最常用的Dinic算法:

    相比于EK(bfs找增广路)、FF(dfs找增广路),dinic算法每次总是寻找最短的增广路,因为在最短增广路的长度在增广过程中始终不会变短.换言之:在dinic的分层图中终点只会变远。所以无需每次都用过 bfs / dfs 来盲目地找增广路,我们可以预先地进行一次 bfs ,将图划成一个分层图,然后在上面尽量地找增广路,直到在该分层图中找不到了(说明最短增广路的长度变长)则再重新构建分层图,如此循环直到构不成分层图。

    复杂度计算:每次构建分层图的复杂度为 O(E),由于每一步 bfs 构建分层图至少使得最短增广路长度增加 1,增广路最长为 V,所以最多构建 O(V) 次。dfs 找增广路的过程如果用当前弧优化,复杂度为 O(E * V)。

    所以总的复杂度:O(V * (E + E * V)) --> O(E * V^2)  

 

 1 const int MAXN = 210;
 2 const int MAXM = 410;
 3 
 4 struct edge{
 5     int v,next,c;
 6 };
 7 
 8 struct Max_flow{
 9     int st,ed,lev[MAXN],first[MAXN],now[MAXN],ecnt;
10     edge e[MAXM];
11     void init(int a,int b){
12         st = a,ed = b;
13         MEM(first,-1);
14         ecnt = 0;
15     }
16     void add_edge(int u,int v,int c){
17         e[ecnt].next = first[u];
18         e[ecnt].v = v;
19         e[ecnt].c = c;
20         first[u] = ecnt++;
21 
22         e[ecnt].next = first[v];
23         e[ecnt].v = u;
24         e[ecnt].c = 0;
25         first[v] = ecnt++;
26     }
27     bool bfs(){
28         queue<int> Q;
29         while(!Q.empty()) Q.pop();
30         Q.push(st);
31         MEM(lev,-1);
32         lev[st] = 0;
33         while(!Q.empty()){
34             int x = Q.front(); Q.pop();
35             for(int i = first[x]; ~i; i = e[i].next){
36                 int v = e[i].v;
37                 if(lev[v] < 0 && e[i].c > 0){
38                     lev[v] = lev[x] + 1;
39                     Q.push(v);
40                 }
41             }
42         }
43         return lev[ed] != -1;
44     }
45     int dfs(int p,int minf){
46         if(p == ed || minf == 0) return minf;
47         for(int &i = now[p]; ~i; i = e[i].next){
48             int v = e[i].v;
49             if(lev[v] == lev[p] + 1 && e[i].c > 0){
50                 int d = dfs(v,min(e[i].c,minf));
51                 if(d > 0){
52                     e[i].c -= d;
53                     e[i ^ 1].c += d;
54                     return d;
55                 }
56             }
57         }
58         return 0;
59     }
60     int dinic(){
61         int max_flow = 0,pl;
62         while(bfs()){
63             memcpy(now,first,sizeof(first));
64             while((pl = dfs(st,INF)) > 0)
65                 max_flow += pl;
66         }
67         return max_flow;
68     }
69 }MF;

 

posted @ 2015-04-08 19:15  Naturain  阅读(351)  评论(0编辑  收藏  举报