返回顶部

洛谷 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<<"\n";
    return 0;
}
posted @ 2020-07-19 20:13  Charles1999  阅读(93)  评论(0)    收藏  举报