Marriage Match IV HDU

题面

点击跳转

题解

以为是价值流, 把 dis[t] 卡着最小值就好了, t飞了

那只能删边, 跑最大流了, 只保留最短路径上的边就好了

s, t正反跑, 把不是最短路上的边直接删了(ne[i] = ne[ne[i]])

代码

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;

const int N = 1e3 + 5, M = 2e5 + 5, inf = 1 << 30;

int n, m, _, k;
int h[N], to[M], ne[M], co[M], tot;
int v[N], incf[N], pre[N], maxflow, d[N], ans, s, t;
int da[N], db[N];

void add(int u, int v, int c) {
    ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
    ne[++tot] = h[v]; to[h[v] = tot] = u; co[tot] = -c;
}

bool bfs() {
    rep (i, 1, n) d[i] = 0;
    queue<int> q; q.push(s); d[s] = 1;
    while (!q.empty()) {
        int x = q.front(); q.pop();
        for (int i = h[x]; i; i = ne[i]) {
            if (!co[i]) continue;
            int y = to[i];
            if (d[y]) continue;
            d[y] = d[x] + 1; q.push(y);
            if (y == t) return 1;
        }
    }
    return 0;
}

int dinic(int x, int flow) {
    if (x == t) return flow;
    int rest = flow, k;
    for (int i = h[x]; i && rest; i = ne[i]) {
        if (!co[i]) continue;
        int y = to[i];
        if (d[y] != d[x] + 1) continue;
        k = dinic(y, min(rest, co[i]));
        if (!k) d[y] = 0;
        co[i] -= k, co[i ^ 1] += k; rest -= k;
    }
    return flow - rest;
}

void dij(int d[], int s, bool f) {
    rep(i, 1, n) d[i] = inf, v[i] = 0; d[s] = 0;
    priority_queue<PII> q; q.push({ 0, s });
    while (!q.empty()) {
        int x = q.top().se; q.pop();
        if (v[x]) continue; v[x] = 1;
        for (int i = h[x]; i; i = ne[i]) {
            if ((i & 1) != f) continue;
            int w = d[x] + abs(co[i]), y = to[i];
            if (w >= d[y]) continue;
            d[y] = w; q.push({ -d[y], y });
        }
    }
}

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m;
        rep(i, 1, n) h[i] = 0;
        tot = 1; maxflow = ans = 0;
        rep(i, 1, m) {
            int u, v, c; cin >> u >> v >> c;
            add(u, v, c);
        }
        cin >> s >> t; dij(da, s, 0); dij(db, t, 1);
        rep (k, 1, n)
            for (int i = h[k], *j = &h[k]; i; i = ne[i])
                if (i & 1)
                    if (db[k] - co[i] + da[to[i]] != db[s]) *j = ne[i];
                    else j = &ne[i], co[i] = 0;
                else
                    if (da[k] + co[i] + db[to[i]] != da[t]) *j = ne[i];
                    else j = &ne[i], co[i] = 1;
        int flow = 0;
        while (bfs()) while (flow = dinic(s, inf)) maxflow += flow;
        cout << maxflow << '
';
    }
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/13827820.html