zoukankan      html  css  js  c++  java
  • 费用流

    #include<bits/stdc++.h>
    using namespace std;
    char buf[1<<20],*_=buf,*__=buf;
    #define gc() (_==__&&(__=(_=buf)+fread(buf,1,1<<20,stdin),_==__)?EOF:*_++)
    #define TT template<class T>inline
    TT bool read(T &x){
        x=0;char c=gc();bool f=0;
        while(c<48||c>57){if(c==EOF)return 0;f^=(c=='-'),c=gc();}
        while(47<c&&c<58)x=(x<<3)+(x<<1)+(c^48),c=gc();
        if(f)x=-x;return 1;
    }
    TT bool read(T&a,T&b){return read(a)&&read(b);}
    TT bool read(T&a,T&b,T&c){return read(a)&&read(b)&&read(c);}
    typedef long long ll;
    const ll MAXN=5008,mod=1e9+7,inf=0x3f3f3f3f;
    struct Mcfm{
        struct E{int y,nt;ll flow,cost;}e[MAXN*20];
        int head[MAXN],cnt=1;
        void add(int x,int y,ll flow,ll cost){//x->y
            e[++cnt].y=y;
            e[cnt].flow=flow;
            e[cnt].cost=cost;
            e[cnt].nt=head[x];head[x]=cnt;
        }
        int n,m,s,t;
        int dis[MAXN],now[MAXN];
        bool vis[MAXN];
        deque<int>que;
        bool spfa(){
            for(int i=0;i<=n;++i)dis[i]=inf,now[i]=head[i];
            que.emplace_back(s),dis[s]=0,vis[s]=1;
            int x,y;
            while(!que.empty()){
                x=que.front(),que.pop_front();
                vis[x]=0;
                for(int i=head[x];i;i=e[i].nt){
                    y=e[i].y;
                    if(e[i].flow>0&&dis[y]>dis[x]+e[i].cost){
                        dis[y]=dis[x]+e[i].cost;
                        if(!vis[y]){
                            if(!que.empty()&&dis[y]<dis[que.front()])
                            	que.emplace_front(y);
                            else que.emplace_back(y);
                            vis[y]=1;
                        }
                    }
                }
            }
            return dis[t]!=inf;
        }
        ll mincost=0,maxflow=0;
        ll dfs(int x,ll totflow){
            if(x==t||totflow==0)return totflow;
            vis[x]=1;
            ll ansflow=0,flow;
            for(int&i=now[x],y;i;i=e[i].nt){
                y=e[i].y;
                if(vis[y]||e[i].flow<=0||dis[x]+e[i].cost!=dis[y])continue;
                flow=dfs(e[i].y,min(totflow,e[i].flow));
                if(flow<=0)dis[y]=-1;
                e[i].flow-=flow;
                e[i^1].flow+=flow;
                totflow-=flow;
                ansflow+=flow;
                mincost+=flow*e[i].cost;
                if(!totflow)break;
            }return vis[x]=0,ansflow;
        }
        void dinic(){
            ll flow;
            while(spfa())
                while((flow=dfs(s,1ll<<50))>0)
            maxflow+=flow;
        }
    }mcfm;
    int main() {
        read(mcfm.n,mcfm.m);read(mcfm.s,mcfm.t);
        int x,y;ll f,c;
        for(int i=0;i<mcfm.m;++i){
            read(x,y);read(f,c);
            mcfm.add(x,y,f,c);
            mcfm.add(y,x,0,-c);
        }
        mcfm.dinic();
        cout<<mcfm.maxflow<<" "<<mcfm.mincost<<endl;
        return 0;
    }
    
    //dijkstra版,需要o2优化不然慢
    struct Mcfm{
        struct E{int y,nt;ll flow,cost;}e[MAXN];
        int head[MAXN],cnt=1;
        void add(int x,int y,ll flow,ll cost){//x->y
            e[++cnt].y=y;
            e[cnt].flow=flow;
            e[cnt].cost=cost;
            e[cnt].nt=head[x];head[x]=cnt;
        }
        int n,m,s,t;
        ll dis[MAXN],h[MAXN];
        bool vis[MAXN];
        void spfa(){
            for(int i=0;i<=n;++i)h[i]=inf;
            queue<int>que;
            que.emplace(s),h[s]=0,vis[s]=1;
            int x,y;
            while(!que.empty()){
                x=que.front(),que.pop();
                vis[x]=0;
                for(int i=head[x];i;i=e[i].nt){
                    y=e[i].y;
                    if(e[i].flow>0&&h[y]>h[x]+e[i].cost){
                        h[y]=h[x]+e[i].cost;
                        if(!vis[y])que.emplace(y),vis[y]=1;
                    }
                }
            }
        }
        ll mincost,maxflow;
        int prep[MAXN],pree[MAXN];
        typedef pair<ll,int>pii;
        priority_queue<pair<ll,int>>que;
        void mcfm(){
            mincost=maxflow=0;
            spfa();
            while(1){
                for(int i=0;i<=n;++i)dis[i]=inf;
                pree[s]=0,prep[s]=0,dis[s]=0;
                while(!que.empty())que.pop();
                que.emplace(0,s);
                while(!que.empty()){
                    pii tmp=que.top();que.pop();
                    int x=tmp.second;
                    if(-tmp.first!=dis[x])continue;
                    for(int i=head[tmp.second],y;i;i=e[i].nt){
                        y=e[i].y;
                        ll len=e[i].cost+h[x]-h[y];
                        if(e[i].flow>0&&dis[y]>dis[x]+len){
                            dis[y]=dis[x]+len;
                            que.emplace(-dis[y],y);
                            pree[y]=i,prep[y]=x;
                        }
                    }
                }
                if(dis[t]==inf)break;
                ll flow=inf;
                for(int i=t;i^s;i=prep[i])flow=min(flow,e[pree[i]].flow);
                for(int i=t;i^s;i=prep[i]){
                    e[pree[i]].flow-=flow;
                    e[pree[i]^1].flow+=flow;
                }
                maxflow+=flow;
                mincost+=flow*(dis[t]+h[t]);
                for(int i=0;i<=n;++i)h[i]=min(h[i]+dis[i],inf);
            }
        }
    }mcfm;
    
  • 相关阅读:
    Chromium(Chrome) frame structure detail
    Chromium(Chrome) Sandbox Details
    ECMA6 New Features
    Asynchronous programming in javascript
    Restful OData Protocol
    java 历年版本特征(简化)
    λ 演算学习
    远程访问其他主机的Mysql(Ubuntu)
    NoSQL基础学习
    Apache solr 6.6.0安装
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14161887.html
Copyright © 2011-2022 走看看