最大流EK算法模板

 

  最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用。

  

 1 #include<cstdio>

 2 #include<cstring>

 3 using namespace std;

 4 

 5 #define _clr(x, y) memset(x, y, sizeof (x))

 6 #define Min(x, y) (x < y ? x : y)

 7 #define INF 0x3f3f3f3f

 8 #define N 210

 9 

10 int map[N][N];

11 int pre[N], Sta[N];

12 bool used[N];

13 int n, m;

14 

15 //bfs判断s--t之间是否还存在增广路

16 bool bfs(int s, int t)

17 {

18     _clr(used, 0);

19     _clr(pre, -1);

20     int top=1;

21     Sta[top++] = s;

22     used[s] = true;

23     while(top)

24     {

25         int v = Sta[--top];

26         for(int i=1; i<=n; i++)

27         {

28             if(map[v][i] && !used[i])

29             {

30                 used[i] = true;

31                 pre[i] = v;

32                 if(i==t)

33                     return true;

34                 Sta[top++] = i;

35             }

36         }

37     }

38     return false;

39 }

40 

41 int EK(int s, int t)

42 {

43     //初始化最大流为0

44     int maxFlow=0, d;

45 

46     //若s--t之间存在增广路

47     while(bfs(s, t))

48     {

49         d = INF;

50         //找到最小的可增量

51         for(int i=t; i!=s; i=pre[i])

52             d = Min(d, map[pre[i]][i]);

53 

54         //添加反向边,更新残留网络

55         for(int i=t; i!=s; i=pre[i])

56         {

57             map[pre[i]][i] -= d;

58             map[i][pre[i]] += d;

59         }

60         maxFlow += d;

61     }

62     return maxFlow;

63 }

64 

65 

66 int main()

67 {

68     int x, y, z;

69     while(~scanf("%d%d", &m, &n))

70     {

71         _clr(map, 0);

72         for(int i=0; i<m; i++)

73         {

74             scanf("%d%d%d",&x, &y, &z);

75             map[x][y] += z;

76         }

77         printf("%d\n",EK(1, n));

78     }

79     return 0;

80 }

 

Fulkersion_ford算法和Ekaf算法基本 是一样的,不同之处在与u搜索增广路时,一个用队列保存,一个用栈保存;

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <queue>

 4 #define _clr(x, y) memset(x, y, sizeof(x))

 5 #define Min(x, y) (x < y ? x : y)

 6 #define INF 0x3f3f3f3f

 7 #define N 110

 8 #define M 1005

 9 using namespace std;

10 

11 int edge[N][N], n;

12 int pre[N], rec[N];

13 int alpha[N], Sta[N];

14 int S, T;

15 

16 void Ford_Fulkerson()

17 {

18     int maxf=0;

19     while(1)

20     {

21         int top=0;

22         _clr(pre, -1);

23         _clr(alpha, 0);

24         pre[S] = S;

25         alpha[S] = INF;

26         Sta[top++] = S;

27         while(top)

28         {

29             int u = Sta[--top];

30             for(int i=0; i<=T; i++)

31             {

32                 if(edge[u][i]>0 && pre[i]==-1)

33                 {

34                     pre[i] = u;

35                     alpha[i] = Min(alpha[u], edge[u][i]);

36                     Sta[top++] = i;

37                 }

38             }

39             if(alpha[T]) break;

40         }

41         if(alpha[T]==0) break;

42 

43         maxf += alpha[T];

44         for(int i=T; i!=S; i=pre[i])

45         {

46             edge[pre[i]][i] -= alpha[T];

47             edge[i][pre[i]] += alpha[T];

48         }

49     }

50     printf("%d\n", maxf);

51 }

52 

53 int main()

54 {

55     int m, num, k;

56     while(~scanf("%d%d", &m, &n))

57     {

58         int pig[M], last[M];

59         S=0, T=n+1;

60         _clr(edge, 0);

61         _clr(last, 0);

62         for(int i=1; i<=m; i++) scanf("%d", pig+i);

63         for(int i=1; i<=n; i++)

64         {

65             scanf("%d", &num);

66             while(num--)

67             {

68                 scanf("%d", &k);

69                 if(last[k]==0)

70                     edge[S][i] += pig[k];

71                 else

72                     edge[last[k]][i] = INF;

73                 last[k] = i;

74             }

75             scanf("%d", &edge[i][T]);

76         }

77         Ford_Fulkerson();

78     }

79     return 0;

80 }
View Code

 

你可能感兴趣的:(最大流)