题面
题解
以为是价值流, 把 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;
}