Network Flow Algorithm sorting

Source: Internet
Author: User

Ek (edmondskarp) algorithm: this algorithm is improved by the Ford-Fulkerson Algorithm. The Ford-Fulkerson Algorithm is constantly used to search for an augmented path, and then judge the minimum traffic of a single path, next, we add a stream to this path. What is different from the FF algorithm is that we use an array to record the minimum traffic of the extended path after extensive search, and then add the stream based on the parent array, time Complexity: O (VE ^ 2)

 

Typedef struct {int flow; // traffic int capacity; // max capacity value} maps; Maps map [maxv] [maxv]; int maxflow; // maximum stream int sp, FP; // mark the Source and Sink point int parent [maxv]; // used for BFs to find the path int vertime; // The total number of vertices int BFS (INT start, int end) {int A [maxv], I, V; queue <int> q; memset (A, 0, sizeof (a); // records the minimum traffic of the extended path, it can also be used as a tag array for extensive search (memset (parent,-1, sizeof (parent); // record this augmented path to increase the stream Q. push (start); A [start] = maxint; while (! Q. Empty () {v = Q. Front (); q. Pop (); for (I = 1; I <= vertime; I ++) {If (! A [I] & map [v] [I]. capacity> map [v] [I]. flow) {// if this is an allowable arc, record Q. push (I); parent [I] = V; A [I] = min (A [v], map [v] [I]. capacity-map [v] [I]. flow) ;}} if (V = END) break; // find the augmented path to exit} return a [end];} void edmondskarp () {int I, TMP; maxflow = 0; while (TMP = BFS (SP, FP) {for (I = FP; I! = Sp; I = parent [I]) {// update the traffic map [I] [Parent [I] based on the parent array. flow-= TMP; // update the reverse flow map [Parent [I] [I]. flow + = TMP; // update the forward stream} maxflow + = TMP ;}}

 

SAP (Shortest Path): first, briefly describe the SAP process:
First, based on the feasible arc (capacity> traffic) layer, the sink point is Layer 1, and the source point is layer d [s ].
...
After the layer, the system constantly searches for extended paths from the source point, and uses the allowable arc (capacity> traffic, and an arc directed by V to u satisfies d [v] = d [u] + 1) search, that is, the number of layers in front is better than the number of layers in the back

In this way, the shortest path can be searched.
......②
When no augmented path is found from the source point, add 1 to the vertex layer referred to by the last viable stream, and then start searching from the source point, that is, perform step 2.
......
When you find an incremental path from the source point, and then find the incremental path from the source point, that is, perform step 1.
......
If d [s]> N-1 is met, the search is exited. Because the graph contains N nodes, a maximum of n-1 layers can be created from 0. If D [s] is greater than n-1 layers, a fault occurs in the middle, we can't find a augmented path.
......
In this way, the complexity of this algorithm is analyzed. The maximum number of m edges in the network can be increased m times. The BFS can be used to increase the complexity. The complexity of a single augmented operation is O (m + n ), where o (m) is the cost of BFS, O (N)

In order to modify the traffic cost, the complexity of searching for the augmented path in each stage is O (m × (m + n) = O (M ^ 2 ), therefore, the complexity of the N-phase augmented path search is O (n × m ^ 2 ).
To sum up, the total complexity of the shortest augmented path algorithm is the sum of the total complexity of building a layered network and the total complexity of searching for augmented paths. It is O (n × m ^ 2)

Int N; // the total number of points int C [maxv] [maxv]; // capacity int R [maxv] [maxv]; // residual int source, sink; // Source Vertex and sink vertex int dis [maxv], maxflow; // layered array and maximum stream void BFS () {int V, I; queue <int> q; memset (DIS, 0, sizeof (DIS); q. push (sink); // The sink point is 0 layer while (! Q. Empty () {v = Q. Front (); q. Pop (); for (I = 0; I <= sink; I ++) {If (! Dis [I] & C [I] [v]> 0) {dis [I] = dis [v] + 1; q. push (I) ;}}} void SAP () {int Top = source, pre [maxv], I, j, low [maxv]; BFS (); // hierarchical memset (low, 0, sizeof (low); // Minimum traffic stored in the path while (DIS [Source] <n) {LOW [Source] = inf; for (I = 0; I <= sink; I ++) {// find a allowed arc if (R [Top] [I]> 0 & dis [Top] = dis [I] + 1) break ;} if (I <= sink) {// The allowable arc low [I] = min (R [Top] [I], low [Top]) is found; // update the current minimum traffic pre [I] = top; Top = I; // record the augmented path if (Top = sink) {// find an augmented path to update the residual volume maxflow + = low [sink]; j = T OP; while (J! = Source) {I = pre [J]; R [I] [J]-= low [sink]; R [J] [I] + = low [sink]; j = I;} Top = source; // find an augmented path from the ground up} else {// cannot find such a path that allows the arc to update the distance from the array int mindis = inf; for (j = 0; j <= sink; j ++) {If (R [Top] [J]> 0 & mindis> dis [J] + 1) mindis = dis [J] + 1;} dis [Top] = mindis; // update the layer of the last blocked stream node if (top! = Source) Top = pre [Top] ;}}

 

Use gap optimization:
That is, when there is a non-continuous label in the label, it can be proved that there is no new augmented flow, and the traffic is the maximum flow at this time.
Simple proof:
If there is no node labeled K, then all nodes can be divided into two parts: d (I)> K, and d (I) <K
This is divided into two parts. Because of the nature of 2, we can see that the allowed path is the shortest augmented path, and because there is no augmented flow from> K to <K, we can see from the theorem that the minimum cut of the maximum stream is

Maximum stream.
SAP + gap + adjacent matrix

# Define INF int_max # define min (A, B) (A> B? B: A) // n indicates the total number of points int sink, source, Res [maxv] [maxv], n; int pre [maxv], DIS [maxv], gap [maxv], maxflow, cur [maxv]; int SAP () {int S = source, t = sink; memset (cur, 0, sizeof (cur )); memset (DIS, 0, sizeof (DIS); memset (GAP, 0, sizeof (GAP); int u = pre [s] = s, Aug = inf, V; maxflow = 0; Gap [Source] = N; while (DIS [s] <n) {loop: For (V = cur [u]; v <n; V ++) if (RES [u] [v] & dis [u] = dis [v] + 1) {cur [u] = V; Aug = min (Aug, res [u] [v]); Pre [v] = u; u = V; If (V = T) {maxflow ++ = Aug; ( U = pre [u]; V! = S; V = u, u = pre [u]) RES [u] [v]-= Aug, Res [v] [u] + = Aug; aug = inf;} goto loop;} int mind = N; For (V = 0; v <n; V ++) if (RES [u] [v] & (mind> dis [v]) {cur [u] = V; mind = dis [v];} if (-- gap [dis [u]) = 0) break; Gap [dis [u] = mind + 1] ++; u = pre [u];} return maxflow ;}

 

SAP + gap + adjacent table

typedef struct{int t,r,contrary,next;}Edge;Edge edge[MAXE];int n,m,source,sink,edge_sum,maxflow;int head[MAXV],dis[MAXV],cur[MAXV],gap[MAXV],pre[MAXV];void sap(){int u=pre[source]=source,tmp=INF,v,a;memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));for(v=0;v<=n;v++) cur[v]=head[v];gap[source]=n;maxflow=0;while(dis[source]<n){loop:for(v=cur[u];v!=-1;v=edge[v].next){a=edge[v].t;if(dis[u]==dis[a]+1 && edge[v].r>0){cur[u]=v;tmp=min(tmp,edge[v].r);pre[a]=u;u=a;if(u==sink){while(u!=source){u=pre[u];edge[cur[u]].r-=tmp;edge[cur[u]^1].r+=tmp;}maxflow+=tmp;tmp=INF;}goto loop;}}int mind=n;for(v=head[u];v!=-1;v=edge[v].next){a=edge[v].t;if(edge[v].r>0 && mind>dis[a]){cur[u]=v;mind=dis[a];}}if((--gap[dis[u]])==0) break;gap[dis[u]=mind+1]++;u=pre[u];}}

 

Dinic algorithm (continuous shortest augmented Path Algorithm ):
First, dinic also uses the layered approach, but it is different from the shortest augmented path:
After sap completes BFS enhancement at each stage, it needs to restart BFs to find an extended path from the source point to the sink point.
Dinic algorithm, as long as a DFS process can find multiple augmented paths, augmented
The following describes the process of the dinic algorithm:
First layer: the source point level is layer 0th, and the sink point level is layer d [T.
...
After the layer, perform a deep search. When the deep search is performed, perform a deep search based on the allowable arc depth (capacity> traffic, in addition, an arc pointing from V to u satisfies d [v] = d [u] + 1), and the current

The minimum traffic and the remaining traffic of the current node. In this way, you can constantly find multiple augmented paths and update them during backtracking. Because you are looking for augmented Paths Based on the allowable arcs, the traffic will be full.

It is the shortest path to seek.
......②
After the deep search is complete, perform the layer again, that is, perform step 1.
......
Analyze the complexity of dinic. In each stage, the cost of moving forward and backward of DFS is O (m × n), because up to n dfs operations can be performed, therefore, the total complexity of finding the augmented path in the dinic Algorithm

O (m × n ^ 2)

 

# Define maxv 410 # define INF int_max # define min (A, B) (A> B? B: A) int res [maxv] [maxv]; // residual intdis [maxv]; // Number of int source, sink, N, and maxflow layers; // s is the Source Vertex, T is the sink vertex int BFS () {int K; queue <int> q; memset (DIS,-1, sizeof (DIS )); dis [sink] = 0; q. push (sink); While (! Q. empty () {k = Q. front (); q. pop (); For (INT I = 0; I <n; I ++) {If (DIS [I] =-1 & res [I] [k]) {dis [I] = dis [k] + 1; q. push (I) ;}} if (k = source) return 1;} return 0;} int DFS (INT cur, int CP) {If (cur = sink) return CP; int TMP = CP, t; for (INT I = 0; I <n & TMP; I ++) {If (DIS [I] + 1 = dis [cur] & res [cur] [I]) {T = DFS (I, min (RES [cur] [I], TMP); Res [cur] [I]-= T; Res [I] [cur] + = T; TMP-= T ;}return CP-TMP;} void dinic () {maxflow = 0; while (BFS () maxflow ++ = DFS (source, INF );}

Joining table: joining table:

Adjacent table:

 

Typedef struct {int S, T, R, next;} edge; edge [MaxE]; int n, m, source, sink, edge_sum, maxflow; int head [maxv], dis [maxv]; int BFS () {int I, V, TMP; queue <int> q; memset (DIS, 0, sizeof (DIS )); dis [Source] = 1; q. push (source); While (! Q. Empty () {v = Q. Front (); q. Pop (); for (I = head [v]; I! =-1; I = edge [I]. Next) {TMP = edge [I]. t; If (! Dis [TMP] & edge [I]. r) {dis [TMP] = dis [v] + 1; if (TMP = sink) return 1; q. push (TMP) ;}}return 0;} int DFS (INT cur, int CP) {If (cur = sink) return CP; int TMP = 0, I, a, T; for (I = head [cur]; I! =-1 & TMP <CP; I = edge [I]. next) {A = edge [I]. t; If (DIS [a] = dis [cur] + 1 & edge [I]. r) {T = DFS (A, min (edge [I]. r, CP-TMP); edge [I]. r-= T; edge [I ^ 1]. R + = T; // reverse side reduction residual TMP + = T ;}} if (! TMP) dis [cur] =-1; // here it indicates that the stream is gone, or this cannot be returned TMP;} void dinic () {maxflow = 0; while (BFS ()) maxflow + = DFS (source, INF );}

 

Relatively speaking, EK and dinic algorithms are easy to implement and debug, and dinic algorithms are highly efficient. Therefore, most people choose dinic algorithms, but sap's gap optimization is effective.

The rate is greater than dinic, so you can choose SAP + gap optimization for the card time.

Maximum fee flow:
For the maximum flow problem, only pay attention to the flow capability of the network flow, without considering the flow cost. In fact, the cost factor is very important. For example, in transportation problems

Under the premise of service, find a transportation solution that saves the most total transportation costs, this is the problem of minimum cost flow. If you only consider the transportation cost of the unit goods, then this problem becomes the shortest

Path Problem, it can be seen that the shortest path problem is the basis of the minimum cost flow problem. There are a series of successful methods to find the shortest path. The minimum charge flow (or the maximum minimum charge flow) problem can be

The greatest stream and the shortest path can be solved by iteration.
In general, the cost is regarded as a model for finding the minimum path. You can set a limit when you are trying to find the shortest path.
Mcmf (spfa) adjacent matrix:

Int source, sink, maxflow, mincost; int res [maxv] [maxv], cost [maxv] [maxv]; int parent [maxv], d [maxv]; void spfa () {queue <int> q; int I, V; bool vis [maxv]; memset (parent,-1, sizeof (parent); memset (VIS, false, sizeof (VIS); for (I = source; I <= sink; I ++) d [I] = inf; d [Source] = 0; q. push (source); vis [Source] = true; while (! Q. empty () {v = Q. front (); q. pop (); vis [v] = false; for (I = 0; I <= sink; I ++) {If (RES [v] [I] & D [v] + cost [v] [I] <D [I]) {d [I] = d [v] + cost [v] [I]; parent [I] = V; If (! Vis [I]) {vis [I] = true; q. push (I) ;}}}} void mcmf () {int V, minflow; maxflow = 0; // the total maximum stream while (1) {spfa (); if (parent [sink] =-1) break; // If the shortest path is not found, exit minflow = inf; // find the shortest path's smallest augmented flow v = sink; while (parent [v]! =-1) {minflow = min (minflow, Res [Parent [v] [v]); V = parent [v];} v = sink; // perform stream augmented while (parent [v]! =-1) {res [Parent [v] [v]-= minflow; Res [v] [Parent [v] + = minflow; V = parent [v];} maxflow + = minflow; mincost + = d [sink] * minflow; // total cost }}

 

Mcmf (spfa) Joining table:

 

# Define INF int_max # define min (A, B) (A> B? B: A) # define maxv 1100 # define maxm 40100 typedef struct {int S, T, next, W, R;} edge; edge [maxm]; int source, sink, n, m, mincost, edgesum; int head [maxv], d [maxv], parent [maxv]; void addedge (int A, int B, int C, int R) {// The undirected edge is required twice. One undirected edge corresponds to four such edge [edgesum]. S = A; edge [edgesum]. T = B; edge [edgesum]. R = r; edge [edgesum]. W = C; edge [edgesum]. next = head [a]; head [a] = edgesum ++; edge [edgesum]. S = B; edge [edgesum]. T = A; edge [edgesum]. r = 0; edge [Edgesum]. W =-C; edge [edgesum]. next = head [B]; head [B] = edgesum ++;} int spfa () {queue <int> q; int V, I, TMP; bool vis [maxv]; for (I = 0; I <= sink; I ++) d [I] = inf; memset (VIS, false, sizeof (VIS )); memset (parent,-1, sizeof (parent); q. push (source); vis [Source] = true; d [Source] = 0; while (! Q. Empty () {v = Q. Front (); q. Pop (); vis [v] = false; for (I = head [v]; I! =-1; I = edge [I]. next) {TMP = edge [I]. t; If (edge [I]. R & edge [I]. W + d [v] <D [TMP]) {d [TMP] = edge [I]. W + d [v]; parent [TMP] = I; If (! Vis [TMP]) {q. push (TMP); vis [TMP] = true ;}}} return 0 ;}void mcmf () {int U, minflow; mincost = 0; while (1) {spfa (); If (parent [sink] =-1) break; minflow = inf; u = parent [sink]; while (u! =-1) {minflow = min (minflow, edge [u]. r); U = parent [edge [u]. s];} u = parent [sink]; while (u! =-1) {edge [u]. r-= minflow; edge [U ^ 1]. R + = minflow; u = parent [edge [u]. s];} mincost + = d [sink] * minflow; maxflow + = minflow ;}}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.