网络流打包

namespace NetWorkFlow{
using namespace std;
#define int long long
#define fi first
#define se second
#define pb emplace_back
//最大流
template<class T>
struct MaxFlow{
	struct edge{
        int v;
        T w;
        edge(int v, T w) : v(v), w(w) {}
    };
    int n;
    T MX = numeric_limits<T>::max();
    vector<edge> G;
    vector<vector<int> > g;
    vector<int> dep, cur;
    MaxFlow(){}
    MaxFlow(int n){init(n);}
    void init(int N){
        n = N;
        G.clear(), g.assign(n, {});
        cur.resize(n), dep.resize(n);
    }
    bool bfs(int s, int t){
        dep.assign(n, -1);
        queue<int> q;
        dep[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i : g[u]){
                //auto [v, w] = G[i];
                int v = G[i].v, w = G[i].w;
                if(w > 0 && dep[v] == -1){
                    dep[v] = dep[u] + 1;
                    if(v == t) return 1;
                    q.push(v);
                }
            }
        }
        return 0;
    }
    T dfs(int u, int t, T f){
        if(u == t) return f;
        auto r = f;
        for(int &i = cur[u]; i < g[u].size(); i++){
            int j = g[u][i];
            //auto [v, w] = G[j];
            int v = G[j].v, w = G[j].w;
            if(w > 0 && dep[v] == dep[u] + 1){
                auto a = dfs(v, t, min(r, w));
                G[j].w -= a;
                G[j ^ 1].w += a;
                r -= a;
                if(r == 0) return f;
            }
        }
        return f - r;
    }
    //加边
    void add(int u, int v, T w){
        g[u].pb(G.size()), G.pb(v, w);
        g[v].pb(G.size()), G.pb(u, 0);
    }
    //最大流
    T flow(int s, int t){
        T ans = 0;
        while(bfs(s, t)){
            cur.assign(n, 0);
            ans += dfs(s, t, MX);
        }
        return ans;
    }
    //最小割
    vector<bool> minCut(){
        vector<bool> w(n);
        for(int i = 0; i < n; i++) w[i] = (dep[i] != -1);
        return w;
    }
    //导出图
    struct Edge{
        int from, to;
        T w, flow;
    };
    vector<Edge> edges(){
        vector<Edge> a;
        for(int i = 0; i < G.size(); i += 2){
            Edge x;
            x.from = G[i + 1].v;
            x.to = G[i].v;
            x.w = G[i].w + G[i + 1].w;
            x.flow = G[i + 1].w;
            a.push_back(x);
        }
        return a;
    }
    //上下界用
    T get_flow(int x){return G[x ^ 1].w;}
    void remove(int x){G[x].w = G[x ^ 1].w = 0;}
};
//Min Cost Max Flow
//最小费用最大流
template<class T>
struct MCMF{
	struct edge{
        int to;
        T w, c;
        edge(int to, T w, T c) : to(to), w(w), c(c) {}
    };
    int n;
    T MX = numeric_limits<T>::max();
    vector<edge> G;
    vector<vector<int> > g;
    vector<T> h, dis;
    vector<int> pre;
    MCMF(){}
    MCMF(int N){init(N);}
    void init(int N){
        n = N;
        G.clear(), g.assign(n, {});
    }
    //加边
    void add(int u, int v, T w, T c){
        g[u].pb(G.size()), G.pb(v, w, c);
        g[v].pb(G.size()), G.pb(u, 0, -c);
    }
    bool dijkstra(int s, int t){
        dis.assign(n, MX);
        pre.assign(n, -1);
        priority_queue<pair<T, int>, vector<pair<T, int> >, greater<pair<T, int> > > q;
        dis[s] = 0;
        q.emplace(0, s);
        while(!q.empty()){
            T d = q.top().fi;
            int u = q.top().se;
            q.pop();
            if(dis[u] != d) continue;
            for(int i : g[u]){
                int v = G[i].to;
                T w = G[i].w, c = G[i].c;
                if(w > 0 && dis[v] > d + h[u] - h[v] + c){
                    dis[v] = d + h[u] - h[v] + c;
                    pre[v] = i;
                    q.emplace(dis[v], v);
                }
            }
        }
        return dis[t] != MX;
    }
    //最大流 and 最小费用
    pair<T, T> flow(int s, int t){
        T flow = 0;
        T c = 0;
        h.assign(n, 0);
        while(dijkstra(s, t)){
            for(int i = 0; i < n; i++) h[i] += dis[i];
            T res = MX;
            for(int i = t; i != s; i = G[pre[i] ^ 1].to){
                res = min(res, G[pre[i]].w);
            }
            for(int i = t; i != s; i = G[pre[i] ^ 1].to){
                G[pre[i]].w -= res;
                G[pre[i] ^ 1].w += res;
            }
            flow += res;
            c += res * h[t];
        }
        return {flow, c};
    }
    //导出图
    struct Edge{
        int from, to;
        T w, c, flow;
    };
    vector<Edge> edges(){
        vector<Edge> a;
        for(int i = 0; i < G.size(); i += 2){
            Edge x;
            x.from = G[i + 1].v;
            x.to = G[i].v;
            x.w = G[i].w + G[i + 1].w;
            x.c = G[i].c;
            x.flow = G[i + 1].w;
            a.push_back(x);
        }
        return a;
    }
};
}
posted @ 2025-08-12 15:36  二项式kimi  阅读(7)  评论(0)    收藏  举报