zoukankan      html  css  js  c++  java
  • 洛谷 P3381 【模板】最小费用最大流

    题目链接

    造了一个最小费用最大流的板子,可根据需求小改,O2优化后可完全AC

    #include <bits/stdc++.h>
    using namespace std;
    class MinCostFlow {
    public:
        struct Result {
            int flow, cost;
        };
    
        MinCostFlow(int n, int m = 0) : visited(n), head(n, -1), dist(n), prev(n) ,flow(n), preu(n){
            edges.reserve(m << 1);
        }
    
        void add_edge(int u, int v, int capacity, int cost) {
            internal_add_edge(u, v, capacity, cost);
            internal_add_edge(v, u, 0, -cost);
        }
    
        bool spfa(int src, int dst) {
            const int infdist = std::numeric_limits<int>::max();
            std::fill(dist.begin(), dist.end(), infdist);
            std::fill(flow.begin(), flow.end(), infdist);
            dist[src] = 0;
            std::queue<int> queue;
            queue.push(src);
            while (!queue.empty()) {
                int u = queue.front();
                queue.pop();
                visited[u] = false;
                for (int iter = head[u]; ~iter;) {
                    int v = edges[iter].v;
                    if (edges[iter].rest && dist[u] + edges[iter].cost < dist[v]) {
                        dist[v] = dist[u] + edges[iter].cost;
                        prev[v] = iter;//上一边
                        preu[v] = u;//前驱点
                        flow[v] = min(flow[u],edges[iter].rest);
                        if (!visited[v]) {
                            visited[v] = true;
                            queue.push(v);
                        }
                    }
                    iter = edges[iter].next;
                }
            }
            return dist[dst]!=infdist;
        }
        Result MCMF(int src,int dst){
            int maxflow=0,mincost=0;
            while(spfa(src,dst)){
                int v=dst;
                maxflow+=flow[dst];
                mincost+=flow[dst]*dist[dst];
                while(v!=src){
                    edges[prev[v]].rest-=flow[dst];
                    edges[prev[v]^1].rest+=flow[dst];
                    v=preu[v];
                }
            }
            return Result{maxflow,mincost};
        }
    
    private:
        struct Edge {
            int v, next, rest, cost;//终点,下条边,容量,花费
        };
    
        void internal_add_edge(int u, int v, int capacity, int cost) {
            edges.push_back(Edge{v, head[u], capacity, cost});
            head[u] = edges.size() - 1;
        }
    
        std::vector<bool> visited;
        std::vector<int> head, dist, prev, flow, preu;
        std::vector<Edge> edges;
    };
    inline int read()
    {
        int X=0; bool flag=1; char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
        while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
        if(flag) return X;
        return ~(X-1);
    }
    
    int main(){
        int n,m,s,t;
        n=read(),m=read(),s=read(),t=read();
        MinCostFlow net(n,m);
        for(int i=0,u,v,w,f;i<m;i++){
            u=read(),v=read(),w=read(),f=read();
            net.add_edge(u-1,v-1,w,f);
        }
        MinCostFlow::Result ans=net.MCMF(s-1,t-1);
        cout<<ans.flow<<" "<<ans.cost<<"
    ";
        return 0;
    }
    
  • 相关阅读:
    第二十一章流 1流的操作 简单
    第二十章友元类与嵌套类 1友元类 简单
    第十九章 19 利用私有继承来实现代码重用 简单
    第二十章友元类与嵌套类 2嵌套类 简单
    第十九章 8链表类Node 简单
    第二十一章流 3用cin输入 简单
    第十九章 10 图书 药品管理系统 简单
    第十九章 11图书 药品管理系统 简单
    第二十一章流 4文件的输入和输出 简单
    第十九章 12 什么时候使用私有继承,什么时候使用包含 简单
  • 原文地址:https://www.cnblogs.com/charles1999/p/13341041.html
Copyright © 2011-2022 走看看