zoukankan      html  css  js  c++  java
  • 有源汇有上下界的最小流(LOJ117)

    一个有源汇有上下界的最小流的瞎那啥讲解

    其实最小流和最大流个人感觉很类似,连接了超级源点和超级汇点之后跑完一次最大流,一个是再在除去超级源点和超级汇点跑一次最大流,一个是给源汇点连一个无限边求最大流,然后无限边的流量就是答案

    因为一个相当于是要把残量网络剩下的流加起来,才是最大流,而这个跑过最大流后剩下的就是最小流了

    代码好像是有点点问题的,LOJ117上一直死跑不过第八个点,但本机上好像是能出正确答案的。。。

    管他的反正也就一个点而已(作为一个蒟蒻能写成这样已经十分满足了,真的菜是没办法的)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll inf=1e15;
    int str,des,cnt=1,adj[50050],nxt[500050],to[500050],lev[50050],low[500050],st,de,m,n;
    ll def[50050],cap[500050];
    inline int read(){
        char ch;
        while((ch=getchar())<'0'||ch>'9'){;}
        int res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
        return res;
    }
    inline void addedge(int u,int v,long long p)
    {
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,cap[cnt]=p;
        nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,cap[cnt]=0;
    }
    inline bool bfs(){
        int u,e,v;
        queue<int> que;
        memset(lev,-1,sizeof(lev));
        que.push(str),lev[str]=0;
        while(!que.empty())
        {
            u=que.front(),que.pop();
            for(int e=adj[u];e;e=nxt[e])
            {
                if(cap[e]>0&&lev[v=to[e]]==-1)
                {
                    lev[v]=lev[u]+1,que.push(v);
                    if(v==des) return true;
                }
            }
        }
        return false;
    }
    inline long long dinic( int u,ll flow)
    {
        if(u==des) return flow;
        ll res=0,flw;
        int v;
        for(int e=adj[u];e;e=nxt[e])
        {
            if(cap[e]>0&&lev[u]<lev[v=to[e]])
            {
                flw=dinic(v,min(cap[e],flow-res));
                if(flw==0) lev[v]=-1;
                cap[e]-=flw,cap[e^1]+=flw;
                res+=flw;if(res==flow) break;
            }
        }
        return res;
    }
    inline long long  solve(){
        long long ans=0;
        while(bfs()==true) ans+=dinic(str,inf);
        return ans;
    }
    int main(){
        n=read(),m=read(),st=read(),de=read();
        int s,t;
        ll up,down;
        long long 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;
        }
        str=0,des=n+1;
        for(int i=1;i<=n;i++)
        {
            if(def[i]>0) addedge(i,des,def[i]);
            if(def[i]<0) addedge(str,i,-def[i]);
        }
        sum=solve();
        addedge(de,st,inf);
        sum+=solve();
        for(int e=adj[des];e;e=nxt[e]) 
        {
            if(cap[e^1]>0)
            {
                cout<<"please go home to sleep"<<'
    ';
                return 0;
            }
        }
        cout<<cap[cnt];
        return 0;
    }
  • 相关阅读:
    iOS开发之--隐藏状态栏
    iOS开发之--iPhone X 适配:MJRefresh上拉加载适配
    iOS开发之--为UITextField监听数值变化的三种方法
    ios开发之--为父view上的子view添加阴影
    iOS开发之--在UIWindow上展示/移除一个View
    iOS开发之--Masonry多个平均布局
    CocoaPods更新过程中出现的坑及解决方法
    那些已成定局的人和事
    两个陌生人的对话
    好好写代码吧,没事别瞎B去创业!
  • 原文地址:https://www.cnblogs.com/forever-/p/9736085.html
Copyright © 2011-2022 走看看