此题建图的疑惑
查看原帖
此题建图的疑惑
482728
Engulf楼主2023/6/1 17:58

此题为了使最大流为 22,新建了一个节点 s′s' 并连一条 s→s′s \to s' 的流量为 22 的边来限制流量,那为什么我在 dfs 增广的时候初始流量不为 ∞ \infty 而是 22 答案就变成 88 了呢?

#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;
}
2023/6/1 17:58
加载中...