hdu1532 最大流板子题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532

题目给出源点和漏点,还有一些边,要求源与漏之间的最大流,我采用了Edmonds Karp算法,该算法是Ford-Fulkerson算法的一种实现,该算法的关键技术是残留网络和残留网络上的反向边,相当于给了搜索策略一个“反悔”的机会,算法的实行过程是每次都寻找一条源点到漏点的增广路径,算出流的大小,每次寻找到一条路径就进行累加直到无法寻找到一条增广路径。寻找增广路径的一般做法是bfs,用dfs的话迭代的次数可能会非常大,十分消耗速度。在Edmonds Karp算法中,一次增广路径的查找需要消耗O(|E|)的时间,在O(|V||E|)次增广之后最大流就能被找到,所以Edmonds Karp 算法的时间复杂度大约是O(|V||E|^2),复杂度在边多的情况下是非常高的,还有其他如Dinic、ISAP算法等最大流算法,本次我先自写一个EdmondsKarp算法。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define mp(a,b) make_pair((a),(b))
17 #define P pair<int,int>
18 #define dbg(args) cout<<#args<<":"<<args<<endl;
19 #define inf 0x3f3f3f3f
20 const int maxn=1005;
21 int n,m,t;
22 inline int read(){
23     int ans=0,w=1;
24     char ch=getchar();
25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
27     return ans*w;
28 }
29 int g[maxn][maxn],pre[maxn];//这里的g数组不但保存了正向边的信息还保存了残留网络的信息
30 int bfs(int src,int sink)
31 {
32     int flow[maxn];
33     mem(pre,-1);
34     flow[src]=inf;pre[src]=0;//每次从源点发出一股无穷大的水流 
35      queue<int> q;q.push(src);
36      while(!q.empty())
37      {
38          int u=q.front();
39          q.pop();
40          if(u==sink)break;//到达漏点
41         f(i,1,n)
42         {
43             if(i!=src&&pre[i]==-1&&g[u][i]>0)//找到一个不是源点而且没有访问过并且与当前点存在边的结点 
44             {
45                 pre[i]=u;
46                 q.push(i);
47                 flow[i]=min(flow[u],g[u][i]);//经过i点之后的源的大小更新成为边的大小或者是前驱结点的较小值 
48             }
49         }
50     }     
51     if(pre[sink]==-1)return -1;//漏点没有被搜索到 
52     return flow[sink]; 
53  } 
54 int maxflow(int src,int sink)
55 {
56     int Maxflow=0;
57     while(1)
58     {
59         int flow=bfs(src,sink);
60         if(flow==-1)break;
61         int cur=sink;//从漏点开始,一步步向源点回退,更新残余网络 
62         while(cur!=src)
63         {
64             int father=pre[cur];
65             g[father][cur]-=flow;//从父结点到当前结点的路径上的流量减少flow
66             g[cur][father]+=flow;//从当前结点到父结点之间增加了一条残余流量
67             cur=father;//回溯更新参与网络 
68         }
69         Maxflow+=flow;
70     }
71     return Maxflow;
72 }
73 int main()
74 {
75     //freopen("input.txt","r",stdin);
76     //freopen("output.txt","w",stdout);
77     std::ios::sync_with_stdio(false);
78     while(scanf("%d%d",&m,&n)!=EOF)
79     {
80         mem(g,0);
81         int u,v,w;
82         f(i,1,m)
83         {
84             u=read(),v=read(),w=read();
85             g[u][v]+=w;
86         }
87         pf("%d\n",maxflow(1,n));
88     }
89 
90 } 

 

posted @ 2020-03-26 15:45  WA自动机~  阅读(219)  评论(0编辑  收藏  举报