zoukankan      html  css  js  c++  java
  • 最小费用最大流板子

    整理一下自己的板子。详细的思路过程,也不太记得了,有空的话再回过头记录把。

    //spfa法 
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=5118,M=51108,inf=0x3f3f3f3f;
    struct Side{
        int v,ne,w,val;
    }S[2*M];
    int s,t,sn,head[N],dis[N],vis[N],flow[N],lu[N];
    void init(int n){
        sn=0;
        for(int i=0;i<=n;i++) head[i]=-1;
    }
    void add(int u,int v,int w,int val){
        S[sn].w=w;
        S[sn].v=v;
        S[sn].val=val;
        S[sn].ne=head[u];
        head[u]=sn++;
    }
    void addE(int u,int v,int w,int val){
        add(u,v,w,val);add(v,u,0,-val);
    }
    bool spfa(int n){
        queue<int> q;
        for(int i=0;i<=n;i++){ 
            dis[i]=inf;
            vis[i]=0;
            flow[i]=inf;
            lu[i]=-1;
        }
        dis[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=S[i].ne){
                int v=S[i].v;
                if(S[i].w>0&&dis[v]>dis[u]+S[i].val){
                    lu[v]=i;
                    dis[v]=dis[u]+S[i].val;
                    flow[v]=min(flow[u],S[i].w);
                    if(!vis[v]){
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return dis[t]!=inf; 
    }
    void mfml(int n){
        int ans=0,ansc=0;
        while(spfa(n)){
            ans+=flow[t];
            ansc+=flow[t]*dis[t];
            for(int i=lu[t];i!=-1;i=lu[S[i^1].v]){
                S[i].w-=flow[t];
                S[i^1].w+=flow[t];
            }
        }
        printf("%d %d
    ",ans,ansc);
    }
    int main(){
        int n,m,u,v,w,val;
        scanf("%d%d%d%d",&n,&m,&s,&t);
        init(n);
        while(m--){
            scanf("%d%d%d%d",&u,&v,&w,&val);
            addE(u,v,w,val);
        }
        mfml(n);
        return 0;
    }
    //zwk费用流 
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=5118,M=51108,inf=1e9+7;
    struct Side{
        int v,ne,w,val;
    }S[M<<1];
    bool vis[N];
    int sb,se,sn,ans,ansc,head[N],dis[N],cur[N];
    void init(int n){
        sn=0;
        for(int i=0;i<=n;i++) head[i]=-1;
    }
    void add(int u,int v,int w,int val){
        S[sn].w=w;S[sn].val=val;
        S[sn].v=v;S[sn].ne=head[u];
        head[u]=sn++;
    }
    void addE(int u,int v,int w,int val){
        add(u,v,w,val);add(v,u,0,-val);
    }
    bool spfa(int n){
        for(int i=0;i<=n;i++){ 
            dis[i]=inf;
            vis[i]=false;
        }
        dis[se]=0;
        vis[se]=true;
        deque<int> q;
        q.push_back(se);
        while(!q.empty()){
            int u=q.front();
            q.pop_front();
            vis[u]=false;
            for(int i=head[u],v;~i;i=S[i].ne){
                v=S[i].v;
                if(S[i^1].w>0&&dis[v]>dis[u]-S[i].val){
                    dis[v]=dis[u]-S[i].val;
                    if(!vis[v]){
                        vis[v]=true;
                        if(!q.empty()&&dis[v]<dis[q.front()])
                            q.push_front(v);
                        else q.push_back(v);
                    }
                }
            }
        }
        return dis[sb]!=inf; 
    }
    int dfs(int u,int minf){
        if(u==se){
            vis[se]=true;
            return minf;
        }
        vis[u]=true;
        int flow=0,temp,v;
        for(int &i=cur[u];~i;i=S[i].ne){
            v=S[i].v;
            if(!vis[v]&&S[i].w>0&&dis[v]==dis[u]-S[i].val){
                temp=dfs(v,min(S[i].w,minf-flow));
                if(temp){
                    S[i].w-=temp;
                    S[i^1].w+=temp;
                    flow+=temp;
                    ansc+=S[i].val*temp; 
                }
                if(flow==minf) break;
            }
        }
        return flow;
    }
    void mfml(int n){
        ans=ansc=0;
        while(spfa(n)){
            do{
                for(int i=0;i<=n;i++) vis[i]=false,cur[i]=head[i];
                ans+=dfs(sb,inf);
            }while(vis[se]);
        }
        printf("%d %d
    ",ans,ansc);
    }
    int main(){
        int n,m,u,v,w,val;
        scanf("%d%d%d%d",&n,&m,&sb,&se);
        init(n);
        while(m--){
            scanf("%d%d%d%d",&u,&v,&w,&val);
            addE(u,v,w,val);
        }
        mfml(n);
        return 0;
    }
    //dijk费用流 
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=5118,M=51108,inf=1e9+7;
    struct Side{
        int v,ne,w,val;
        Side(){}
        Side(int v,int val):v(v),val(val){}
        bool operator<(const Side &s1)const{
            return val>s1.val;
        }
    }S[M<<1];
    bool vis[N];
    int n,sb,se,sn,ansc,head[N],dis[N],flow[N],lu[N],h[N];
    void init(int n){
        sn=0;
        for(int i=0;i<=n;i++) head[i]=-1;
    }
    void add(int u,int v,int w,int val){
        S[sn].w=w;S[sn].val=val;
        S[sn].v=v;S[sn].ne=head[u];
        head[u]=sn++;
    }
    void addE(int u,int v,int w,int val){
        add(u,v,w,val);add(v,u,0,-val); 
    }
    bool dijk(){
        priority_queue<Side> q;
        for(int i=0;i<=n;i++){
            lu[i]=-1;    
            dis[i]=flow[i]=inf;
        }
        dis[sb]=0;
        q.push(Side(sb,dis[sb]));
        while(!q.empty()){
            int u=q.top().v,w=q.top().val;q.pop();
            if(dis[u]<w) continue;
            for(int i=head[u];~i;i=S[i].ne){
                int v=S[i].v;
                if(S[i].w>0&&dis[v]>dis[u]+S[i].val+h[u]-h[v]){
                    lu[v]=i;
                    dis[v]=dis[u]+S[i].val+h[u]-h[v];
                    flow[v]=min(flow[u],S[i].w);
                    q.push(Side(v,dis[v]));
                }
            }
        }
        return dis[se]!=inf; 
    }
    int mfml(){
        int ans=0,ansc=0;
        for(int i=0;i<=n;i++) h[i]=0;
        while(dijk()){
            ans+=flow[se];
            ansc+=flow[se]*(dis[se]+h[se]-h[sb]);
            for(int i=lu[se];~i;i=lu[S[i^1].v]){
                S[i].w-=flow[se];
                S[i^1].w+=flow[se];
            }
            for(int i=0;i<=n;i++) h[i]+=dis[i];
        }
        printf("%d %d
    ",ans,ansc); 
        return 0;
    }
    int main(){
        int m,u,v,w,val;
        scanf("%d%d%d%d",&n,&m,&sb,&se);
        init(n);
        while(m--){
            scanf("%d%d%d%d",&u,&v,&w,&val);
            addE(u,v,w,val);
        }
        mfml();
        return 0;
    }

    平常题spfa便可以过,毒瘤的时候,可以使用势函数优化的dijkstra版本,zwk费用流在某些数据(稠密图)下是最快的。

  • 相关阅读:
    Weblogic 12c 集群部署和session复制
    Weblogic 12c 集群环境搭建
    Programming In Scala笔记-第十九章、类型参数,协变逆变,上界下界
    这是最好的时光,这是最坏的时光 SNAPSHOT
    这是最好的时光 这是最坏的时光 v0.1.1.1
    鹅厂欧阳大神给年轻人的一些分享
    谈到电影,我们收获了什么
    那些被电影搞的日子
    Programming In Scala笔记-第十五章、Case Classes和模式匹配
    [CSharp]传一个包含多个属性的对象,只改变其中个别属性值的方法
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/13290197.html
Copyright © 2011-2022 走看看