• 费用流模板


    很好理解的,,按最大流思路理解就行  用优先队列优化复杂度低一点

    //#include<iostream>
    //#include<cstdio>
    //#include<cstring>
    //#include<cmath>
    //#include<queue>
    //#include<set>
    //#include<algorithm>
    //#include<map>
    //#define maxn 200005
    //typedef long long ll;
    //#define inf 100000009
    //using namespace std;
    //struct edge{
    //int to,cap,cost,rev;   //终点,容量,费用,反向边
    //};
    //int n,V;
    //vector<edge>G[maxn];
    //int dis[maxn];
    //int prevv[maxn];  //最短路中的前驱结点
    //int preve[maxn];  //最短路中对应的边
    //
    ////向图中增加一条从from到头容量为cap费用为cost的边;
    //void add_edge(int from,int to,int cap,int cost)
    //{
    //    G[from].push_back((edge){to,cap,cost,G[to].size()});
    //    G[to].push_back((edge){from,0,-cost,G[from].size()-1});
    //}
    //
    ////求解从s到t流量为f的最小费用流
    ////如果不能再增广则返回-1
    //int min_cost_flow(int V,int s,int t,int f)
    //{
    //    int res=0;
    //    //cout<<V<<endl;
    //    while(f>0)
    //    {
    //        fill(dis,dis+V,inf);
    //        dis[s]=0;
    //        bool vis=true;
    //        while(vis)
    //        {
    //            //cout<<dis[3]<<endl;
    //            // cout<<"a"<<endl;
    //            vis=false;
    //            //cout<<"a"<<endl;
    //           // cout<<n<<endl;
    //            for(int i=0;i<V;i++)
    //            {
    //                //cout<<dis[i]<<endl;
    //                if(dis[i]==inf)continue;
    //                for(int j=0;j<G[i].size();j++)
    //                {
    //                    edge &e=G[i][j];
    //                    //cout<<e.cap<<endl;
    //                    if(e.cap>0&&dis[e.to]>dis[i]+e.cost)
    //                    {
    //                        dis[e.to]=dis[i]+e.cost;
    //                        prevv[e.to]=i;
    //                        preve[e.to]=j;
    //                        vis=true;
    //                        //cout<<"vis"<<endl;
    //                    }
    //                }
    //            }
    //           // cout<<vis<<endl;
    //        }
    //        if(dis[t]==inf)return -1;  //表示不能增广
    //        //沿s到t的最短路尽量增广
    //         int d=f;
    //         for(int i=t;i!=s;i=prevv[i])
    //         {
    //             d=min(d,G[prevv[i]][preve[i]].cap);
    //         }
    //         f-=d;
    //         res+=d*dis[t];
    //         for(int i=t;i!=s;i=prevv[i])
    //         {
    //             edge &e=G[prevv[i]][preve[i]];
    //             e.cap-=d;
    //             G[i][e.rev].cap+=d;
    //         }
    //    }
    //    return res;
    //}
    //int main()
    //{
    //    int n,k;
    //    cin>>n>>k;
    //    int s1,t1,f1;
    //    int x,y,z,l;
    //    for(int i=0;i<k;i++)
    //    {
    //        cin>>x>>y>>z>>l;
    //        add_edge(x,y,z,l);
    //    }
    //    cin>>s1>>t1>>f1;
    //    cout<<min_cost_flow(n,s1,t1,f1)<<endl;
    //    return 0;
    //}
    
    
    
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<algorithm>
    #include<map>
    #define maxn 20005
    #define inf 1000000009
    typedef long long ll;
    using namespace std;
    typedef pair<int,int>P;   //first保存最短距离   second保存顶点编号
    struct edge{
    int to,cap,cost,rev;
    };
    vector<edge>G[maxn];
    int h[maxn];    //顶点的势
    int dis[maxn];  //最短距离
    int prevv[maxn]; //最短路中的前驱结点
    int preve[maxn];   //最短路中的边
    //建图
    void add_edge(int from,int to,int cap,int cost)
    {
        G[from].push_back((edge){to,cap,cost,G[to].size()});
        G[to].push_back((edge){from,0,-cost,G[from].size()-1});
    }
    //求解从s到t流量为f的最小费用流
    //如果不能再增广则返回-1
    int min_cost_flow(int V,int s,int t,int f)
    {
        int res=0;
        fill(h,h+V,0);
        while(f>0)
        {
            priority_queue<P, vector<P>, greater<P> >que;
            fill(dis,dis+V,inf);
            dis[s]=0;
            que.push(P(0,s));
            while(!que.empty())
            {
                P p=que.top();
                que.pop();
                int v=p.second;
                if(dis[v]<p.first)continue;
                for(int i=0;i<G[v].size();i++)
                {
                    edge &e=G[v][i];
                    if(e.cap>0&&dis[e.to]>dis[v]+e.cost+h[v]-h[e.to])
                    {
                        dis[e.to]=dis[v]+e.cost+h[v]-h[e.to];
                        prevv[e.to]=v;
                        preve[e.to]=i;
                        que.push(P(dis[e.to],e.to));
                    }
                }
            }
            if(dis[t]==inf)return -1;
            for(int i=0;i<V;i++)
            {
                h[i]+=dis[i];
            }
            int d=f;
            for(int i=t;i!=s;i=prevv[i])
            {
                d=min(d,G[prevv[i]][preve[i]].cap);
            }
            f-=d;
            res+=d*h[t];
            for(int i=t;i!=s;i=prevv[i])
            {
                edge &e=G[prevv[i]][preve[i]];
                e.cap-=d;
                G[i][e.rev].cap+=d;
            }
        }
        return res;
    }
    int main()
    {
        int n,k;
        cin>>n>>k;
        int s1,t1,f1;
        int x,y,z,l;
        for(int i=0;i<k;i++)
        {
            cin>>x>>y>>z>>l;
            add_edge(x,y,z,l);
        }
        cin>>s1>>t1>>f1;
        cout<<min_cost_flow(n,s1,t1,f1)<<endl;
        return 0;
    }
  • 相关阅读:
    第十三课:js操作节点的创建
    matlab 绘制条形图
    Pearson(皮尔逊)相关系数及MATLAB实现
    Spearman Rank(斯皮尔曼等级)相关系数及MATLAB实现
    A Regularized Competition Model for Question Diffi culty Estimation in Community Question Answering Services-20160520
    Competition-based User Expertise Score Estimation-20160520
    We Know What @You #Tag: Does the Dual Role Affect Hashtag Adoption-20160520
    matlab 画图数据导入
    Who Says What to Whom on Twitter-www2011-20160512
    The Lifecycle and Cascade of WeChat Social Messaging Groups-www2016-20160512
  • 原文地址:https://www.cnblogs.com/huangzzz/p/9458709.html
Copyright © 2020-2023  润新知