Original http://blog.csdn.net/a1dark/article/details/11177907
Edmondskarp algorithm, abbreviated as EK algorithm, O (m^2n)
because it is a beginner tutorial, so I will try to avoid complicated mathematical formulas and proofs. Also try to give a more complete code.
the target group of this article is a beginner of the network flow, especially to see a variety of NB tutorials did not understand how to find the best flow of small pots of friends. The purpose of this article is to explain the basic network flow model, the most basic of the maximum flow method, that is, BFS find the augmented road method, that is, the Ek method, the full name is edmond-karp, in fact, I think that the full name of the algorithm and the origin can be taken out from time to load a pack.
for example, the EK algorithm was first proposed by Russian scientist Dinic in 1970, yes, dinic algorithm is the founder, in fact, he proposed is Dinic algorithm, on the basis of the EK added to the level optimization, this we will say later, 1972 Jack Edmonds and Richard Karp published an EK algorithm without hierarchical Optimization. But in fact they came out of independence earlier than 1790.
you see, it's also interesting to study history.
Pull away, First look at the basic network flow maximum flow model.
there are n points, there is a forward edge of M bar, a point is very special, only out, called the source point, usually specified as 1th points. The other point is also very special, only can not enter, called the meeting point, usually specified as n point. Each having a forward edge has two quantities, capacity and flow, the capacity from I to J is usually expressed in c[i,j], the flow is usually f[i,j]. These edges can usually be imagined as a road, traffic is the flow of the road, capacity is the road can withstand the largest traffic. It is clear that the flow <= Capacity. For each point that is not a source and sink point, it can be imagined as a stopover for goods without storage functions, all "into" their traffic and equal to all the traffic from him "out".
the problem with comparing the source point to the factory is to ask for the maximum number of goods that can be emitted from the factory, which is not to exceed the capacity limit of the road, that is, the maximum flow.
like this picture. The number next to each edge indicates its Capacity.
Let's consider how to find the maximum flow.
first, If the traffic on all sides does not exceed capacity (not greater than capacity), then this group of traffic, or, This flow, is called a viable stream. One of the simplest examples is that 0 streams, that is, all traffic is 0 streams.
We start with this 0 stream, and if there is such a path, the road has been connected to the meeting point from the source point, and every segment of the road satisfies the flow < capacity, attention, is strictly < instead of <=. well, we can certainly find the minimum delta in each segment of the path (capacity-flow). We add this delta to each segment of the road, and it's clear that this flow is still a viable flow.
So we get a bigger stream, his traffic is the previous traffic +delta, and this road is called the augmented path.
We constantly look for the augmented path from the starting point, augmenting it each time until the source and sink are not connected, that is, the augmentation path is not found. When the augmented path is not found, the current flow is the maximum flow, the conclusion is very important.
When looking for an augmented path we can simply start with the BFS from the source, and constantly modify the delta on this road until the source point is found or the augmented path is Missing.
Here is to add that, in the implementation of the program, we usually just use a C array to record capacity, and not to record traffic, when the traffic +1, We can implement it through capacity-to facilitate the implementation of the Program.
Semi-pseudo code for the BFS process: the following is another C + + version of the template
intBFS () {inti,j,k,v,u; Memset (pre,-1,sizeof(pre)); for(i=1; I<=n;++i) flow[i]=max_int; Queue<int>que; pre[start]=0; Que.push (start); while(!Que.empty ()) {v=Que.front (); Que.pop (); for(i=1; i<=n;++I) {u=i; if(u==start| | pre[u]!=-1|| map[v][u]==0)Continue; pre[u]=v; flow[u]=MIN (flow[v],map[v][u]); Que.push (u); } } if(flow[end]==max_int)return-1; returnflow[end];}
But in fact it is not so simple, the above-mentioned augmentation path is not complete, such as the following network flow Model.
The first time we found the 1-2-3-4, the delta was obviously 1. So we modified it and got the following Stream. (the number in the figure is the Capacity)
At this time and (3,4) side of the traffic is equal to the capacity, we can no longer find the other augmented road, the current flow is 1.
But the answer is obviously not the maximum flow, because we can go 1-2-4 and 1-3-4 at the same time, so we can get a flow of 2.
So where's the problem with the algorithm we just had? The problem is that we do not give the program a "regret" opportunity, there should be a 2-3-4 (2-4) and change the Mechanism. So how do we solve this problem? Search backwards? Then our efficiency goes up to an exponential level.
And this algorithm magically uses a concept called the opposite side to solve the Problem. That is, each edge (i,j) has a reverse edge (j,i), and the opposite Edge also has its Capacity.
We look directly at how it is resolved:
After the first finding of the augmentation path, the capacity of each segment of the road is reduced by delta, and the counter-direction capacity of each segment is increased by Delta. At the same time as Dec (c[x,y],delta), Inc (c[y,x],delta)
Let's take a look at the example above, and after finding the 1-2-3-4 this augmented road, change the capacity to the following
Then find the augmented road, you will find 1-3-2-4 this can be augmented, that is, the delta value of 1 can be augmented road. After this path is augmented, the maximum flow is 2.
So why would it be right to do so? Let me explain it in a popular way.
In fact, when our second augmented road 3-2 this opposite side, it is equivalent to 2-3 this positive edge is already used flow to "back" back, do not go 2-3 this road, and change away from 2 points from the other road is 2-4. (someone asked if there is no 2-4 what to do, then if there is no 2-4 this road, eventually this augmented road will not exist, because he could not go to the meeting Point) at the same time, the flow from the 3-4 is 1-3-4 this road to "take over." And finally 2-3 this road is going to flow 1, reverse flow 1, equals no traffic.
This is the essence of the algorithm, using the opposite edge, so that the program has a chance to regret and Correct. And this algorithm compared to the code that I just gave a word more than a sentence.
The template is as Follows:
#include <iostream>#include<queue>using namespacestd;Const intmaxn=205;Const intinf=0x7fffffff;intr[maxn][maxn];//residual network, initialized to originalBOOLvisit[maxn];intpre[maxn];intm,n;BOOLBFsintSintT//looking for an augmented path from S to t, if found returns True{ intp; Queue<int>q; Memset (pre,-1,sizeof(pre)); Memset (visit,false,sizeof(visit)); pre[s]=s; visit[s]=true; Q.push (s); while(!Q.empty ()) {p=Q.front (); Q.pop (); for(intI=1; i<=n;i++) { if(r[p][i]>0&&!visit[i]) {pre[i]=p; visit[i]=true; if(i==t)return true; Q.push (i); } } } return false;}intEdmondskarp (intSintT) { intflow=0, d,i; while(bfs (s,t)) {d=inf; for(i=t;i!=s;i=pre[i]) D=d<r[pre[i]][i]?d:r[pre[i]][i]; for(i=t;i!=s;i=pre[i]) {r[pre[i]][i]-=d; r[i][pre[i]]+=d; } Flow+=d; } returnflow;}intmain () { while(SCANF ("%d%d", &m,&n)! =EOF) { intu,v,w; Memset (r,0,sizeof(r));/// for(intI=0; i<m;i++) {scanf ("%d%d%d",&u,&v,&w); r[u][v]+=w; } printf ("%d\n", Edmondskarp (1, n)); } return 0;}
"go" Network maximum Flow--ek algorithm detailed