Flow Problem 最大流 最小增廣路 SAP算法 從EK算法的753MS降到了46MS

EK 算法的鏈接:http://blog.csdn.net/ipqhjjybj/article/details/9171181

SAP算法果然對這個優化了好多。。時間直接從753MS降到46MS呀。。

題目描述

Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.

Input:

The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)


  1. #include <cstdio>  
  2. #include <cmath>  
  3. #include <cstdlib>  
  4. #include <ctime>  
  5.   
  6. #include <iostream>  
  7. #include <cmath>  
  8. #include <algorithm>  
  9. #include <numeric>  
  10. #include <utility>  
  11.   
  12. #include <cstring>  
  13. #include <vector>  
  14. #include <stack>  
  15. #include <queue>  
  16. #include <map>  
  17. #include <string>  
  18. using namespace std;  
  19.   
  20. #define inf 0x3f3f3f3f  
  21. #define MAXN 20  
  22. #define MAXM 1005  
  23. #define clr(x,k) memset((x),(k),sizeof(x))  
  24. #define cpy(x,k) memcpy((x),(k),sizeof(x))  
  25. #define Base 10000  
  26.   
  27. typedef vector<int> vi;  
  28. typedef stack<int> si;  
  29. typedef vector<string> vs;  
  30. #define sz(a) int((a).size())  
  31. #define pb push_back  
  32. #define all(c) (c).begin(),(c).end()  
  33. #define rep(i,n) for(int i = 0;i < n;++i)  
  34. #define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)  
  35.   
  36. #define max(a,b) ((a)>(b)?(a):(b))  
  37. #define min(a,b) ((a)<(b)?(a):(b))  
  38.   
  39. struct node{  
  40.     int c,next,to;  
  41. }edges[MAXM];  
  42. int box[MAXN],n,m,tot;  
  43. void add(int a,int b,int c){  
  44.     edges[tot].to=b;  
  45.     edges[tot].c=c;  
  46.     edges[tot].next=box[a];  
  47.     box[a]=tot++;  
  48. }  
  49. int Map[MAXN][MAXN]; //map:鄰接數組 因爲可能有重邊情況。優化下,再用SAP算法  
  50. void init(){  
  51.     clr(Map,0);  
  52.     for(int i = 0,a,b,c;i < m;i++){  
  53.         scanf("%d %d %d",&a,&b,&c);  
  54.         Map[a][b] += c;  
  55.     }  
  56.     tot=2;  
  57.     clr(box,-1);  
  58.     for(int i = 1;i <= n;i++)  
  59.         for(int j = 1;j <= n;j++)  
  60.             if(Map[i][j])  
  61.                 add(i,j,Map[i][j]),add(j,i,0);  
  62. }  
  63. int SAP_Max_Flow(int start,int end,int N){  
  64.     int numh[MAXN],h[MAXN],curedges[MAXN],pre[MAXN];  
  65.     //numh: 用於GAP優化的統計高度數量數組;h:距離標號數組;curedges;當前弧數組,pre,前驅數組  
  66.     int cur_flow,flow_ans=0,u,tmp,neck,i;  
  67.     clr(h,0);  
  68.     clr(numh,0);  
  69.     clr(pre,-1);  
  70.     for(i = 1;i <= n;i++)  
  71.         curedges[i]=box[i];  
  72.     numh[0]=N;  
  73.     u=start;  
  74.     while(h[start]<N){  
  75.         if(u==end){  
  76.             cur_flow=inf;  
  77.             for(i=start;i!=end;i=edges[curedges[i]].to){  
  78.                 if(cur_flow>edges[curedges[i]].c){  
  79.                     neck=i;  
  80.                     cur_flow=edges[curedges[i]].c;  
  81.                 }  
  82.             }  
  83.             for(i=start;i!=end;i=edges[curedges[i]].to){  
  84.                 tmp=curedges[i];  
  85.                 edges[tmp].c-=cur_flow;  
  86.                 edges[tmp^1].c+=cur_flow;  
  87.             }  
  88.             flow_ans+=cur_flow;  
  89.             u=neck;  
  90.         }  
  91.         for(i=curedges[u];i!=-1;i=edges[i].next){  
  92.             if(edges[i].c&&h[u]==h[edges[i].to]+1)  
  93.                 break;  
  94.         }  
  95.         if(i!=-1){  
  96.             curedges[u]=i;  
  97.             pre[edges[i].to]=u;  
  98.             u=edges[i].to;  
  99.         }  
  100.         else{  
  101.             if(0==--numh[h[u]])break;  
  102.             curedges[u]=box[u];  
  103.             for(tmp=N,i=box[u];i!=-1;i=edges[i].next)  
  104.                 if(edges[i].c)  
  105.                     tmp=min(tmp,h[edges[i].to]);  
  106.             h[u]=tmp+1;  
  107.             ++numh[h[u]];  
  108.             if(u!=start) u=pre[u];  
  109.         }  
  110.     }  
  111.     return flow_ans;  
  112. }  
  113. int main(){  
  114.     //freopen("3549.in","r",stdin);  
  115.     int t,tt=0;  
  116.     scanf("%d",&t);  
  117.     while(t--){  
  118.         scanf("%d %d",&n,&m);  
  119.         init();  
  120.         printf("Case %d: %d\n",++tt,SAP_Max_Flow(1,n,n));  
  121.     }  
  122.     return 0;  
  123. }  
發佈了28 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章