• LOJ117 有源汇有上下界最小流(上下界网络流)


      跑出可行流后从原来的汇点向原来的源点跑最大流,原图最小流=inf-maxflow。显然超源超汇的相关边对其也没有影响。原图最小流=可行流-原图新增流量,因为t向s流量增加相当于s向t流量减少。但为什么等于inf-maxflow呢?显然最大流会把这条inf边跑满,这样会增加inf-可行流的流量,然后又继续在原图中增加可增加的流量,移项就可以得到这个式子了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 50010
    #define M 500000
    #define S 0
    #define T 50001
    #define inf 1000000000
    int n,m,w,v,t=-1,p[N],degree[N],l[M],tot=0;
    int cur[N],d[N],q[N],ans=0;
    struct data{int to,nxt,cap,flow;
    }edge[M];
    void addedge(int x,int y,int z)
    {
        t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=0,p[x]=t;
        t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=0,edge[t].flow=0,p[y]=t;
    }
    bool bfs(int s,int t)
    {
        memset(d,255,sizeof(d));d[s]=0;
        int head=0,tail=1;q[1]=s;
        do
        {
            int x=q[++head];
            for (int i=p[x];~i;i=edge[i].nxt)
            if (d[edge[i].to]==-1&&edge[i].flow<edge[i].cap)
            {
                d[edge[i].to]=d[x]+1;
                q[++tail]=edge[i].to;
            }
        }while (head<tail);
        return ~d[t];
    }
    int work(int k,int f,int t)
    {
        if (k==t) return f;
        int used=0;
        for (int i=cur[k];~i;i=edge[i].nxt)
        if (d[k]+1==d[edge[i].to])
        {
            int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow),t);
            edge[i].flow+=w,edge[i^1].flow-=w;
            if (edge[i].flow<edge[i].cap) cur[k]=i;
            used+=w;if (used==f) return f;
        }
        if (used==0) d[k]=-1;
        return used;
    }
    void dinic(int s,int t)
    {
        while (bfs(s,t))
        {
            memcpy(cur,p,sizeof(p));
            ans+=work(s,inf,t);
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("loj117.in","r",stdin);
        freopen("loj117.out","w",stdout);
        const char LL[]="%I64d";
    #else
        const char LL[]="%lld";
    #endif
        n=read(),m=read(),w=read(),v=read();
        memset(p,255,sizeof(p));
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read(),low=read(),high=read();
            addedge(x,y,high-low);
            degree[y]+=low,degree[x]-=low;
            l[i]=low;
        }
        for (int i=1;i<=n;i++)
        if (degree[i]>0) addedge(S,i,degree[i]),tot+=degree[i];
        else if (degree[i]<0) addedge(i,T,-degree[i]);
        addedge(v,w,inf);
        dinic(S,T);
        if (ans<tot) cout<<"please go home to sleep";
        else ans=0,dinic(v,w),cout<<inf-ans;
        return 0;
    }
  • 相关阅读:
    背水一战 Windows 10 (26)
    背水一战 Windows 10 (25)
    背水一战 Windows 10 (24)
    背水一战 Windows 10 (23)
    背水一战 Windows 10 (22)
    背水一战 Windows 10 (21)
    背水一战 Windows 10 (20)
    背水一战 Windows 10 (19)
    背水一战 Windows 10 (18)
    背水一战 Windows 10 (17)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9420549.html
Copyright © 2020-2023  润新知