此题为了使最大流为 2,新建了一个节点 s′ 并连一条 s→s′ 的流量为 2 的边来限制流量,那为什么我在 dfs 增广的时候初始流量不为 ∞ 而是 2 答案就变成 8 了呢?
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
#ifdef ONLINE_JUDGE
#define debug(...) 0
#else
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#endif
const int N = 1e6, M = 1e6;
int n, m, s, ss, t;
int mincost;
struct edge {
int to, nxt;
int flow;
int cost;
}e[M << 1];
int cur[N], head[N], ecnt = 1;
void add(int x, int y, int w, int c) {
e[++ecnt] = {y, head[x], w, c}, head[x] = ecnt;
e[++ecnt] = {x, head[y], 0, -c}, head[y] = ecnt;
}
int dis[N];
bitset<N> vis;
bool spfa() {
memcpy(cur, head, sizeof head);
memset(dis, 0x3f, sizeof dis);
queue<int> q;
q.push(s);
dis[s] = 0;
vis[s] = 1;
while (!q.empty()) {
int u = q.front(); q.pop(); vis[u] = 0;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (dis[v] > dis[u] + e[i].cost && e[i].flow) {
dis[v] = dis[u] + e[i].cost;
if (!vis[v]) {
vis[v] = 1;
q.push(v);
}
}
}
}
return dis[t] != inf;
}
int dfs(int u, int in) {
if (u == t) return in;
vis[u] = 1;
int out = 0;
for (int i = cur[u]; i && in; i = e[i].nxt) {
int v = e[i].to;
cur[u] = i;
if (e[i].flow && !vis[v] && dis[v] == dis[u] + e[i].cost) {
int fl = dfs(v, min(e[i].flow, in));
mincost += fl * e[i].cost;
in -= fl, out += fl;
e[i].flow -= fl, e[i ^ 1].flow += fl;
}
}
vis[u] = 0;
return out;
}
struct Pac {
int x, y;
bool operator<(const Pac &b) const {return x ^ b.x ? x < b.x : y < b.y;}
}p[2005];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
s = n * 2 + 1, ss = s + 1, t = ss + 1;
add(s, ss, 2, 0);
for (int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
sort(p + 1, p + n + 1);
for (int i = 1; i <= n; i++) {
int mn = inf;
for (int j = i + 1; j <= n; j++)
if (p[j].y < mn && p[j].y >= p[i].y) {
add(i + n, j, inf, 0);
mn = p[j].y;
}
}
for (int i = 1; i <= n; i++) {
add(ss, i, 2, 0);
add(i, i + n, 1, -1);
add(i, i + n, 1, 0);
add(i + n, t, 2, 0);
}
while (spfa()) dfs(s, inf);
cout << -mincost << endl;
return 0;
}