[Template] dijstra minimum cost maximum flow

int cnt;
int h[maxn];
int prep[maxn];
int pree[maxm];
int dis[maxn];
int st = maxn - 2;
int ed = maxn - 1;

struct Edge
{
    int v, nxt;
    int w, f;
}e[maxm];

int head[maxn];

inline void init()
{
    memset(head, -1, sizeof(head));
    cnt = 1;
}

inline void add(int u, int v, int w, int f)
{
    e[++cnt].v = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
    e[cnt].f = f;
    e[cnt].w = w;
    e[++cnt].v = u;
    e[cnt].nxt = head[v];
    head[v] = cnt;
    e[cnt].f = -f;
    e[cnt].w = 0;
}

inline pair<int, int> dijstra()
{
    int maxf = 0;
    int minc = 0;
    while (1)
    {
        priority_queue<pair<int, int>>heap;
        memset(dis, 0x3f, sizeof(dis));
        dis[st] = 0;
        heap.push(make_pair(0, st));
        while (!heap.empty())
        {
            pair<int, int> x = heap.top();
            heap.pop();
            if (-x.first != dis[x.second]) continue;
            if (x.second == ed) break;
            for (int i = head[x.second]; i != -1; i = e[i].nxt)
            {
                int now = e[i].f + h[x.second] - h[e[i].v];
                if (e[i].w > 0 && dis[e[i].v] > dis[x.second] + now)
                {
                    dis[e[i].v] = dis[x.second] + now;
                    heap.push(make_pair(-dis[e[i].v], e[i].v));
                    prep[e[i].v] = x.second;
                    pree[e[i].v] = i;
                }
            }
        }
        if (dis[ed] >= 0x3f3f3f3f) break;
        for (int i = 0; i <= n; i++) h[i] += dis[i];
        int now = 0x3f3f3f3f;
        for (int i = ed; i != st; i = prep[i])
            now = min(now, e[pree[i]].w);
        for (int i = ed; i != st; i = prep[i])
        {
            e[pree[i]].w -= now;
            e[pree[i] ^ 1].w += now;
        }
        maxf += now;
        minc += now * h[ed];
    }
    return make_pair(maxf, minc);
}

 

Guess you like

Origin www.cnblogs.com/thjkhdf12/p/11942282.html