[Template] bounds network flow

There passive sinks lower and upper bounds feasible flow:

Problem: given a map, each side must flow between $ $ [l, r], you find it's a legitimate stream.

Consider a initial idea: each edge is split into two, a flow rate of $ $ L, a flow rate of $ rl $.

Q: Can we consider only side to build a program just like the original drawing $ rl $, running a legitimate stream, and finally add all $ l $ is not on line yet?

A: Obviously not, because all $ l $ are not equal, so after you add $ l $ meet the original flow balance does not meet the flow chart of balance. ( And passive sink without running out of bounds is 0 ah )

But we can see, with respect to the original, all traffic must flow $ l $ is generated out of thin air, but out of thin air is absorbed.

And simple network flow problem is also based on a source to generate traffic, a sink point traffic to achieve.

So the question of the processing flow balance we can do this:

Create a super source connected to each edge point to indicate flow into the point; a new super-sink, which is connected to the edge of each point indicates the point away from the flow.

Then run a maximum flow, if the full flow specification to meet the requirements under the conditions of flow balance, otherwise not meet the requirements explained in the flow equilibrium conditions.

More specifically, we can:

New source $ S $, sink $ T $.

For an edge $ (u, v, l, r) $, we even three sides: $ (S, v, l) $, $ (u, T, l) $, $ (u, v, rl) $.

Edge $ (S, v, l) $ $ V $ that enter at least if the flow rate of $ l $.

Edge $ (u, T, l) $ $ U $ represents traffic leaving at least if the $ l $.

Edge $ (u, v, rl) $ represent additional traffic flow over the $ l $ no lower bound, the upper bound is $ rl $.

Then we from $ S $ to $ T $ ran maximum flow.

FIG finish after this inspection, if and only if any of the drawing point U $ $ $ S are satisfied with the presence of the entire view of licit T $ edges are even full flow.

(If a point less than the maximum flow and the entire flow chart is then adjusted in any case there will be less than a flow point, this time point on the edge of the picture is less than the flow rate constant in the presence of $ $ L)

(No need to check the $> r $ conditions, because if $> r $ substandard law must be because it causes some point $ <l $'m not lawful)

This determination may be simplified to the maximum flow condition = $ S $ traffic flow of all of the edges and a = $ T $ and all the edges.

If there is a legitimate case each stream is directly output $ (u, v, rl) of the edge flow $ $ + l $ can.

 

Code ( loj115 ):

#include<bits/stdc++.h>
#define maxn 205
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl

using  namespace std;
int hd [maxn], lim [MaxM] to [MaxM], NXT [MaxM] fl [MaxM];
int S, T, cnt = 1 , id [MaxM], dis [maxn], INQ [maxn];

inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

inline void addedge(int u,int v,int w){
    to[++cnt]=v,fl[cnt]=w,nxt[cnt]=hd[u],hd[u]=cnt;
    to[++cnt]=u,fl[cnt]=0,nxt[cnt]=hd[v],hd[v]=cnt;
}

inline bool spfa(){
    memset(dis,63,sizeof(dis));
    memset(inq,0,sizeof(inq));
    queue<int> q;q.push(S);
    dis[S]=0,inq[S]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop(),inq[u]=0;
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i],w=fl[i];
            if(w>0&&dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                if(!inq[v]) q.push(v),inq[v]=1;
            }
        }
    }
    return dis[T]!=dis[T+1];
}
inline int dfs(int u,int flow){
    int sum=0;
    if(u==T) return flow;
    for(int i=hd[u];i;i=nxt[i]){
        int v=to[i];
        if(dis[v]==dis[u]+1 && fl[i]>0){
            int f=dfs(v,min(flow,fl[i]));
            sum+=f,fl[i]-=f,fl[i^1]+=f,flow-=f;
        }
        if(!flow) break;
    }
    if(sum==0) dis[u]=-1;
    return sum;
}
inline int Dinic(){int ans=0;while(spfa())ans+=dfs(S,inf);return ans;}

int main(){
    int n=read(),m=read();S=0,T=n+1;
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        lim[i]=read(); int r=read();
        addedge(S,v,lim[i]),addedge(u,T,lim[i]);
        addedge(u,v,r-lim[i]),id[i]=cnt;
    }
    Dinic(); int flag=1;
    for(int i=hd[S];i;i=nxt[i]) if(fl[i]!=0) flag=0;
    for(int i=hd[T];i;i=nxt[i]) if(fl[i^1]!=0) flag=0;
    if(!flag) printf("NO\n");
    else{
        printf("YES\n");
        for(int i=1;i<=m;i++)
            printf("%d\n",fl[id[i]]+lim[i]);
    }
    return 0;
}
loj115

 

There is an active exchange bounds maximum flow:

When this FIG given source point $ S '$, sink $ T' $, which no longer meet the flow balance, we could not seem to deal with.

However, according to the Idea, from the $ T '$ to $ S' $ not even a $ (0, inf) $ edges, this figure would meet the balance of the flow ......

But we ran out by the above method is not necessarily the original maximum flow, how to do it?

Consider an idea: to run again on the residual network over $ S '$ to $ T' $ maximum flow, how?

Notes that came out of the residual network on the new map must flow balance, then we run again in addition to the maximum flow will not affect the $ S ', T' $ traffic from all points of balance.

And, because we will not only come to $ S $ or $ T $ ran along the edge of the original, so I finally ran out of stream must still legal (did not affect the determination of the legal conditions).

So run twice the maximum flow can solve this problem.

The second time running when not considering the first pass answer, because the first pass ran $ S $-point flow balance, corresponds to the initial flow rate is zero.

 

Code ( loj116 ):

#include<bits/stdc++.h>
#define maxn 205
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl

using  namespace std;
int hd [maxn], lim [MaxM] to [MaxM], NXT [MaxM] fl [MaxM];
int S, T, cnt = 1 , id [MaxM], dis [maxn], INQ [maxn];

inline int read(){
    int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

inline void addedge(int u,int v,int w){
    to[++cnt]=v,fl[cnt]=w,nxt[cnt]=hd[u],hd[u]=cnt;
    to[++cnt]=u,fl[cnt]=0,nxt[cnt]=hd[v],hd[v]=cnt;
}

inline bool spfa(){
    memset(dis,63,sizeof(dis));
    memset(inq,0,sizeof(inq));
    queue<int> q;q.push(S);
    dis[S]=0,inq[S]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop(),inq[u]=0;
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i],w=fl[i];
            if(w>0&&dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                if(!inq[v]) q.push(v),inq[v]=1;
            }
        }
    }
    return dis[T]!=dis[T+1];
}
inline int dfs(int u,int flow){
    int sum=0;
    if(u==T) return flow;
    for(int i=hd[u];i;i=nxt[i]){
        int v=to[i];
        if(dis[v]==dis[u]+1 && fl[i]>0){
            int f=dfs(v,min(flow,fl[i]));
            sum+=f,fl[i]-=f,fl[i^1]+=f,flow-=f;
        }
        if(!flow) break;
    }
    if(sum==0) dis[u]=-1;
    return sum;
}
inline int Dinic(){int ans=0;while(spfa())ans+=dfs(S,inf);return ans;}

int main(){
    int n=read(),m=read(),s=read(),t=read(); 
    S=0,T=n+1; int sum=0,u,v,r;
    for(int i=1;i<=m+1;i++){
        if(i==m+1) u=t,v=s,lim[i]=0,r=inf;
        else u=read(),v=read(),lim[i]=read(),r=read();
        addedge(S,v,lim[i]),addedge(u,T,lim[i]),addedge(u,v,r-lim[i]),id[i]=cnt,sum+=lim[i]; 
    }
    int mx=Dinic(); 
    if(sum!=mx) printf("please go home to sleep\n");
    else S=s,T=t,printf("%d\n",Dinic());
    return 0;
}
loj116

Guess you like

Origin www.cnblogs.com/YSFAC/p/12057346.html