Getting Started with maximum flow stream (from general optimization algorithm to dinic)

Network flow (network-flows) is a solution to the problem of water analogy, it is closely related to linear programming. Network flow theory and application of continuous development. And we talk about today is the network flow in a common problem - the maximum flow problem.

The maximum flow problem (maximum flow problem), combination optimization problems, is to discuss how the ability to take full advantage of the device so that the maximum flow of transport in order to achieve the best results. Seeking maximum flow of the labeling algorithm was first proposed by Ford and Fokker McPherson and 1956, "the network flow theory" Ford (Ford), (Fulkerson) established in the 1950s, is an important component of network applications.

Before then to address this problem, we must first understand some definitions :

image

Network is a flow diagram is only one source and sink of a directed graph, and the maximum flow is seeking the source point to the maximum water flow between the sink, issue the following figure is a basic, classic maximum flow problem

image

II. Flow rate, flow volume and viable

For arc (u, v), the flow of the water is flowing through it (we usually represented by f (u, v)), while the capacity is the maximum amount of water (usually We c (u, v may flow thereon ) represents), as long as f (u, v) <= c (u, v), we call flow f (u, v) is feasible flow (for the maximum flow problem, traffic on all pipelines must both feasible flow).

III. Augmenting path

image

If all sides of a road are true:

Forward edge: f (u, v) <c (u, v) --- reverse side: f (u, v)> 0

If there is such a road, the road from the beginning has been the source of a section connected to the sink, and each section of this road traffic are met <capacity, pay attention, is strictly <instead of <=. So, we will be able to find each section of this road - among the minimum delta value (flow capacity) of. We each section of this road traffic are adding the delta, we will be able to ensure that this flow is still feasible flow. In this way we get a bigger stream, his flow of traffic before + delta, and this road is called augmenting paths. From the network flow (Network Flow)

We call this the path to an augmenting path, referred to as augmenting paths.

Well, to understand some definitions, then you can introduce the famous Ford-Fulkerson algorithm of.

image

As shown, if we always find an augmenting path, as long as this passage through augmenting sink, that the water flow can also be described at this time increased by an amount d (d = min (d, c ( u, v) -f (u, v)) or d = min (d, f (u, v))).

We can interpret it this way: For each positive side, he can add a maximum water flow to c (u, v) -f (u, v). As for the reverse side, when the forward edge of the water flow increases, the reverse side of their reverse flow will be reduced, but it can reduce the amount of water most of f (u, v). Since then added water to ensure that all f (u, v) are feasible flow, so we take the minimum.

After the increase, we want to update traffic, each forward edge + d, -d to each reverse side.

In this case, our idea is:

1. Find an augmenting path --2. Modify the values ​​on which the point --3. 1 continues to repeat until not find augmenting paths. At this time, the amount of the export source point is also desired maximum flow.

image

image

image

image

image

Then on the code:

#include<bits/stdc++.h>
#include<vector>
#define maxn 1200
#define INF 2e9
using namespace std;
int i,j,k,n,m,h,t,tot,ans,st,en;
struct node{
    int c,f;
}edge[maxn][maxn];
int flag[maxn],pre[maxn],alpha[maxn],q[maxn],v;
int read(){
    char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
    while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}

void bfs(){
    memset(flag,0xff,sizeof(flag));memset(pre,0xff,sizeof(pre));memset(alpha,0xff,sizeof(alpha));
    flag[st]=0;pre[st]=0;alpha[st]=INF;h=0,t=1;q[t]=st;
    while(h<t){
        h++;v=q[h];
        for(int i=1;i<=n;i++){
            if(flag[i]==-1){
                if(edge[v][i].c<INF&&edge[v][i].f<edge[v][i].c){
                    flag[i]=0;pre[i]=v;alpha[i]=min(alpha[v],edge[v][i].c-edge[v][i].f);q[++t]=i;
                }
                else if(edge[i][v].c<INF&&edge[i][v].f>0){
                    flag[i]=0;pre[i]=-v;alpha[i]=min(alpha[v],edge[i][v].f);q[++t]=i;
                }
            }
        }
        flag[v]=1;
    }
}

void Ford_Fulkerson(){
    while(1){
        bfs();
        if(alpha[en]==0||flag[en]==-1){
            break;
        }
        int k1=en,k2=abs(pre[k1]);int a=alpha[en];
        while(1){
            if(edge[k2][k1].c<INF) edge[k2][k1].f+=a;
            else if(edge[k1][k2].c<INF) edge[k1][k2].f-=a;
            if(k2==st) break;
            k1=k2;k2=abs(pre[k1]);
        }
        alpha[en]=0;
    }
}

void flow(){
    int maxflow=0;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++){
        if(i==st&&edge[i][j].f<INF) maxflow+=edge[i][j].f;
      }
    printf("%d",maxflow);
}

int main(){
    int u,v,c,f;
    n=read();m=read();st=read();en=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++) edge[i][j].c=INF,edge[i][j].f=0;
    for(int i=1;i<=m;i++){
        u=read();v=read();c=read();
        edge[u][v].c=c;
    }
    Ford_Fulkerson();
    flow();
    return 0;
}

Guess you like

Origin www.cnblogs.com/linhaostudy/p/12133852.html