最小费用最大流(最小增广路算法)

来源:互联网 发布:期货盈利交易系统优化 编辑:程序博客网 时间:2024/05/16 04:58

基于BellmanFord(SPFA),无法处理负权环(结果出错)。

struct Edge{    int from, to, cap, flow, cost;}struct MCMF{    int n, m, s, t;    vector<Edge> edges;    vector<int> g[N];    int inq[N];             //是否在队列中     int d[N];               //最小费用     int p[N];               //上一条弧     int a[N];               //可改进量     void init(int n){        this->n = n;        for(int i = 0; i < n; i++) g[i].clear();        edges.clear();    }    void AddEdge(int from, int to, int cap, int cost){        edges.push_back((Edge){from, to, cap, 0, cost});        edges.push_back((Edge){to, from, 0, 0, -cost});        m = edges.size();        g[from].push_back(m-2);        g[to].push_back(m-1);    }};bool BellmanFord(int s, int t, int& flow, int& cost){    for(int i = 0; i < n; i++) d[i] = inf;    memset(inq, 0, sizeof(inq));    d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;    queue<int> Q;    Q.push(s);    while(!Q.empty()){        int u = Q.front(); Q.pop();        inq[u] = 0;        for(int i = 0; i < g[u].size(); i++){            Edge& e = edges[g[u][i]];            if(e.cap > e.flow && d[e.to] > d[u] + e.cost){                d[e.to] = d[u] + e.cost;                p[e.to] = g[u][i];                a[e.to] = min(a[u], e.cap - e.flow);                if(!inq[e.to]){q.push(e.to); inq[e.to] = 1;}            }        }    }    if(d[t] == inf) return false;    flow += a[t];    cost += d[t] * a[t];    int u = t;    while(u != s){        edges[p[u]].flow += a[t];        edges[p[u]^1].flow -= a[t];        u = edges[p[u]].from;    }    return true;}int Mincost(int s, int t){    int flow = 0, cost = 0;    while(BellmanFord(s, t, flow, cost));    return cost;}
0 0