zoukankan      html  css  js  c++  java
  • 有上下界网络流模板

    115. 无源汇有上下界可行流

    n 个点,m 条边,每条边 e  有一个流量下界 lower(e)和流量上界 upper(e)),求一种可行方案使得在所有点满足流量平衡条件的前提下,所有边满足流量限制。

    输入格式

    第一行两个正整数 n 、m 。

    之后的 m  行,每行四个整数 s、t 、lower 、upper。

    输出格式

    如果无解,输出一行 NO

    否则第一行输出 YES,之后 m  行每行一个整数,表示每条边的流量。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=70005;
    int sp,tp,cnt=0,head[205],nxt[maxn],to[maxn],cap[maxn],dis[1005],low[maxn],def[205],m,n;
    inline int read(){
        int ans=0; char last=' ',ch=getchar();
        while(ch<'0' || ch>'9')last=ch,ch=getchar();
        while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
        if(last=='-')ans=-ans; return ans;
    }
    inline void add(int u,int v,int p){
        nxt[cnt]=head[u],to[cnt]=v,cap[cnt]=p,head[u]=cnt++;
        nxt[cnt]=head[v],to[cnt]=u,cap[cnt]=0,head[v]=cnt++;
    }
    inline bool bfs(){
        int u,e,v;
        queue<int> que;
        memset(dis,-1,sizeof(dis));
        que.push(sp),dis[sp]=0;
        while(!que.empty()){
            u=que.front(),que.pop();
            for(int e=head[u];~e;e=nxt[e]){
                if(cap[e]>0&&dis[v=to[e]]==-1){
                    dis[v]=dis[u]+1,que.push(v);
                    if(v==tp) return true;
                }
            }
        }
        return false;
    }
    inline int dfs(const int &u,const int &flow){
        if(u==tp) return flow;
        int res=0,v,flw;
        for(int e=head[u];~e;e=nxt[e]){
            if(cap[e]>0&&dis[u]<dis[v=to[e]]){
                flw=dfs(v,min(cap[e],flow-res));
                if(flw==0) dis[v]=-1;
                cap[e]-=flw,cap[e^1]+=flw;
                res+=flw;
                if(res==flow) break;
            }
        }
        return res;
    }
    inline int dinic(int sp,int tp){
        int ans=0;
        while(bfs()) {
            ans+=dfs(sp,1<<30);
        }
        return ans;
    }
    int main(){
        memset(head,-1,sizeof(head));
        n=read(),m=read();
        int s,t,up,down,sum=0;
        for(int i=1;i<=m;i++){
            s=read(),t=read(),down=read(),up=read();
            add(s,t,up-down);
            low[i]=down,def[s]+=down,def[t]-=down;
        }
        sp=n+1,tp=n+2;
        for(int i=1;i<=n;i++){
            if(def[i]>0) sum+=def[i],add(i,tp,def[i]);
            if(def[i]<0) add(sp,i,-def[i]);
        }
        if(dinic(sp,tp)==sum){
            cout<<"YES"<<endl;
            for(int i=1;i<=m;i++){
                cout<<cap[((i-1)*2)^1]+low[i]<<endl;
            }
        }
        else cout<<"NO"<<endl;
        return 0;
    }
    View Code

    #116. 有源汇有上下界最大流

    n 个点,m 条边,每条边 e  有一个流量下界 lower(e)和流量上界 upper(e) ,给定源点 s  与汇点 t ,求源点到汇点的最大流。

    输入格式

    第一行两个正整数 n、m、s、t。

    之后的 m 行,每行四个整数 s、t、lower、upper。

    输出格式

    如果无解,输出一行 please go home to sleep

    否则输出最大流。

    样例输入

    1.  
      10 15 9 10
    2.  
      9 1 17 18
    3.  
      9 2 12 13
    4.  
      9 3 11 12
    5.  
      1 5 3 4
    6.  
      1 6 6 7
    7.  
      1 7 7 8
    8.  
      2 5 9 10
    9.  
      2 6 2 3
    10.  
      2 7 0 1
    11.  
      3 5 3 4
    12.  
      3 6 1 2
    13.  
      3 7 6 7
    14.  
      5 10 16 17
    15.  
      6 10 10 11
    16.  
      7 10 14 15

    样例输出

    43

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=70005;
    int sp,tp,cnt=1,head[205],nxt[maxn],to[maxn],cap[maxn],dis[1005],low[maxn],st,de,def[205],m,n;
    inline int read(){
        int ans=0; char last=' ',ch=getchar();
        while(ch<'0' || ch>'9')last=ch,ch=getchar();
        while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
        if(last=='-')ans=-ans; return ans;
    }
    inline void addedge(int u,int v,int p){
        nxt[++cnt]=head[u],head[u]=cnt,to[cnt]=v,cap[cnt]=p;
        nxt[++cnt]=head[v],head[v]=cnt,to[cnt]=u,cap[cnt]=0;
    }
    inline bool bfs(){
        int u,e,v;
        queue<int> que;
        memset(dis,-1,sizeof(dis));
        que.push(sp),dis[sp]=0;
        while(!que.empty()){
            u=que.front(),que.pop();
            for(int e=head[u];e;e=nxt[e]){
                if(cap[e]>0&&dis[v=to[e]]==-1){
                    dis[v]=dis[u]+1,que.push(v);
                    if(v==tp) return true;
                }
            }
        }
        return false;
    }
    inline int dfs(const int &u,const int &flow){
        if(u==tp) return flow;
        int res=0,v,flw;
        for(int e=head[u];e;e=nxt[e]){
            if(cap[e]>0&&dis[u]<dis[v=to[e]]){
                flw=dfs(v,min(cap[e],flow-res));
                if(flw==0) dis[v]=-1;
                cap[e]-=flw,cap[e^1]+=flw;
                res+=flw;if(res==flow) break;
            }
        }
        return res;
    }
    inline int dinic(int sp,int tp){
        int ans=0;
        while(bfs()) {
            ans+=dfs(sp,1<<30);
        }
        return ans;
    }
    int main(){
        memset(head,-1,sizeof(head));
        n=read(),m=read(),st=read(),de=read();
        int s,t,up,down,sum=0;
        for(int i=1;i<=m;i++){
            s=read(),t=read(),down=read(),up=read();
            addedge(s,t,up-down);
            low[i]=down,def[s]+=down,def[t]-=down;
        }
        sp=n+1,tp=n+2;
        for(int i=1;i<=n;i++){
            if(def[i]>0) sum+=def[i],addedge(i,tp,def[i]);
            if(def[i]<0) addedge(sp,i,-def[i]);
        }
        addedge(de,st,1<<30);
        if(dinic(sp,tp)==sum){
            head[sp]=0,head[tp]=0;
            sp=st;
            tp=de;
            cout<<dinic(sp,tp)<<endl;
        }
        else cout<<"please go home to sleep"<<endl;
        return 0;
    }
    View Code
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=70005;
    int sp,tp,cnt=1,head[205],nxt[maxn],to[maxn],cap[maxn],dis[1005],low[maxn],st,de,def[205],m,n;
    inline int read(){
        int ans=0; char last=' ',ch=getchar();
        while(ch<'0' || ch>'9')last=ch,ch=getchar();
        while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
        if(last=='-')ans=-ans; return ans;
    }
    inline void addedge(int u,int v,int p){
        nxt[++cnt]=head[u],head[u]=cnt,to[cnt]=v,cap[cnt]=p;
        nxt[++cnt]=head[v],head[v]=cnt,to[cnt]=u,cap[cnt]=0;
    }
    inline bool bfs(){
        int u,e,v;
        queue<int> que;
        memset(dis,-1,sizeof(dis));
        que.push(sp),dis[sp]=0;
        while(!que.empty()){
            u=que.front(),que.pop();
            for(int e=head[u];e;e=nxt[e]){
                if(cap[e]>0&&dis[v=to[e]]==-1){
                    dis[v]=dis[u]+1,que.push(v);
                    if(v==tp) return true;
                }
            }
        }
        return false;
    }
    inline int dfs(const int &u,const int &flow){
        if(u==tp) return flow;
        int res=0,v,flw;
        for(int e=head[u];e;e=nxt[e]){
            if(cap[e]>0&&dis[u]<dis[v=to[e]]){
                flw=dfs(v,min(cap[e],flow-res));
                if(flw==0) dis[v]=-1;
                cap[e]-=flw,cap[e^1]+=flw;
                res+=flw;if(res==flow) break;
            }
        }
        return res;
    }
    inline int dinic(int sp,int tp){
        int ans=0;
        while(bfs()) {
            ans+=dfs(sp,1<<30);
        }
        return ans;
    }
    int main(){
        memset(head,-1,sizeof(head));
        n=read(),m=read(),st=read(),de=read();
        int s,t,up,down,sum=0;
        for(int i=1;i<=m;i++){
            s=read(),t=read(),down=read(),up=read();
            addedge(s,t,up-down);
            low[i]=down,def[s]+=down,def[t]-=down;
        }
        sp=n+1,tp=n+2;
        for(int i=1;i<=n;i++){
            if(def[i]>0) sum+=def[i],addedge(i,tp,def[i]);
            if(def[i]<0) addedge(sp,i,-def[i]);
        }
        addedge(de,st,1<<30);
        if(dinic(sp,tp)==sum){
            head[sp]=0,head[tp]=0;
            sp=st;
            tp=de;
            cout<<dinic(sp,tp)<<endl;
        }
        else cout<<"please go home to sleep"<<endl;
        return 0;
    }
    View Code

    #117. 有源汇有上下界最小流

    n 个点,m 条边,每条边 e 有一个流量下界 lower(e) 和流量上界 upper(e),给定源点 s 与汇点 t,求源点到汇点的最小流。

    输入格式

    第一行两个正整数 n、m、s、t。

    之后的 m 行,每行四个整数 s、t、lower、upper。

    输出格式

    如果无解,输出一行 please go home to sleep

    否则输出最小流。

    样例输入

    1.  
      7 12 6 7
    2.  
      6 1 0 2147483647
    3.  
      1 7 0 2147483647
    4.  
      6 2 0 2147483647
    5.  
      2 7 0 2147483647
    6.  
      6 3 0 2147483647
    7.  
      3 7 0 2147483647
    8.  
      6 4 0 2147483647
    9.  
      4 7 0 2147483647
    10.  
      6 5 0 2147483647
    11.  
      5 7 0 2147483647
    12.  
      5 1 1 2147483647
    13.  
      3 4 1 2147483647

    样例输出

    2

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<queue>
    #define inf 0x7fffffff
    using namespace std;
    const int maxn=50010;
    const int maxm=405000;
    int n,m,sp,tp,s,t;
    int nxt[maxm],head[maxn],to[maxm],cap[maxm],cnt=0,deg[maxn];
    int cur[maxm],dis[maxm];
    inline  int read(){
        int ans=0; char last=' ',ch=getchar();
        while(ch<'0' || ch>'9')last=ch,ch=getchar();
        while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
        if(last=='-')ans=-ans; return ans;
    }
    inline void add(int u,int v,int p){
        nxt[cnt]=head[u],to[cnt]=v,cap[cnt]=p,head[u]=cnt++;
        nxt[cnt]=head[v],to[cnt]=u,cap[cnt]=0,head[v]=cnt++;
    }
    bool bfs(int st,int en){
        memset(dis,-1,sizeof(dis));
        memcpy(cur,head,sizeof(head));
        queue<int > q;
        q.push(st);dis[st]=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int e=head[u];~e;e=nxt[e]){
                int v=to[e];
                if(cap[e]>0&&dis[v]==-1){
                    dis[v]=dis[u]+1;
                    if(v==en) return true;
                    q.push(v);
                }
            }
        }
        return false;
    }
    inline int dinic(int u,int flow,int ee){
        if(u==ee) return flow;
        int res=0;
        for(int &e=cur[u];~e;e=nxt[e]){
            int v=to[e];
            if(cap[e]>0&&dis[v]>dis[u]){
                int delta=dinic(v,min(flow-res,cap[e]),ee);
                if(delta){
                    cap[e]-=delta;cap[e^1]+=delta;
                    res+=delta;
                    if(res==flow) break;
                }
            }
        }
        return res;
    }
     
    int main(){
        memset(head,-1,sizeof(head));
        n=read();m=read();s=read();t=read();
        int i,j,k;
        sp=0;tp=n+1;
        for(i=1;i<=m;++i){
            int u=read(),v=read(),ll=read(),rr=read();
            add(u,v,rr-ll);
            deg[v]+=ll;  deg[u]-=ll;
        }
        int sum=0,first;
        add(t,s,inf);
        first=cnt-1;
        for(i=1;i<=n;++i){
            if(deg[i]<0)
                add(i,tp,-deg[i]);
            else if(deg[i]>0)
                add(sp,i,deg[i]),sum+=deg[i];
        }
        int maxflow=0;
        while(bfs(sp,tp))
            maxflow+=dinic(sp,inf,tp);
        if(maxflow==sum){
            maxflow=cap[first];
            for(i=first-1;i<=cnt;++i) cap[i]=0;
            while(bfs(t,s)) maxflow-=dinic(t,inf,s);
            printf("%d
    ",maxflow);
        }
        else printf("please go home to sleep
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    Netty事件监听和处理(上)
    Netty事件监听和处理(上)
    Netty事件监听和处理(上)
    nginx 反向代理转发导致css,js,图片失效
    nginx 反向代理转发导致css,js,图片失效
    nginx 反向代理转发导致css,js,图片失效
    【leetcode】507.Perfect Number
    【leetcode】507.Perfect Number
    【leetcode】507.Perfect Number
    Javascript中的类实现
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9627113.html
Copyright © 2011-2022 走看看