HDU 3549 Flow Problem(最大流模版EK算法)

本文深入解析了最大流EK算法的过程,并通过实例代码展示了如何应用该算法解决实际问题。详细介绍了BFS查找路径、更新流量等核心步骤,帮助读者理解和掌握最大流算法的基本原理。

题目链接

第一道最大流,赤裸裸的模版题,刚好可以熟悉模版用。今天看了一下最大流,就看了一个EK算法,感觉有点和二分图匹配算法有点相似,对于最大流问题有点了解了,不过为什么这么做,也不是 很懂,只是把代码给敲了一遍,以后慢慢学习。

EK算法,过程是先BFS找到str到end的一条路,然后每条路上的流量(key[][]记录)取这些路中流量的最小值(flow[]记录),在这条路上的流量都减去这个值,然后建立反向边,然后继续找增广路,直到找不到为止。有前驱的结点不会再找了,所以几遍之后肯定找不到了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <cmath>
 5 #include <queue>
 6 using namespace std;
 7 #define INF 0x7fffffff
 8 int key[101][101];
 9 int path[101],flow[101],n,m,str,end;
10 queue<int>que;
11 int bfs()
12 {
13     int i,t;
14     while(!que.empty()) que.pop();
15     memset(path,-1,sizeof(path));
16     path[str] = 0;
17     flow[str] = INF;//初始化
18     que.push(str);
19     while(!que.empty())//BFS
20     {
21         t = que.front();
22         que.pop();
23         if(t == end) break;//已经找到end了
24         for(i = 1;i <= n;i ++)
25         {
26             if(i != str&&key[t][i]&&path[i] == -1)
27             {
28                 flow[i] = flow[t] < key[t][i] ? flow[t]:key[t][i];//记录流量
29                 que.push(i);
30                 path[i] = t;//记录前驱
31             }
32         }
33     }
34     if(path[end] == -1)//找不到路径时
35     return -1;
36     else
37     return flow[end];
38 }
39 int EK()
40 {
41     int ans = 0,pre,now,step;
42     while((step = bfs()) != -1)
43     {
44         ans += step;
45         now = end;
46         while(now != str)
47         {
48             pre = path[now];
49             key[now][pre] += step;
50             key[pre][now] -= step;
51             now = pre;
52         }
53     }
54     return ans;
55 }
56 int main()
57 {
58     int i,t,sv,ev,w,num = 0;
59     scanf("%d",&t);
60     while(t--)
61     {
62         num ++;
63         memset(key,0,sizeof(key));
64         scanf("%d%d",&n,&m);
65         for(i = 1;i <= m;i ++)
66         {
67             scanf("%d%d%d",&sv,&ev,&w);
68             key[sv][ev] += w;
69         }
70         str = 1;end = n;
71         printf("Case %d: %d\n",num,EK());
72     }
73     return 0;
74 }

 

转载于:https://www.cnblogs.com/naix-x/archive/2012/11/20/2779611.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值