社区讨论

求调 54pts

P6577【模板】二分图最大权完美匹配参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mib61s80
此快照首次捕获于
2025/11/23 11:36
4 个月前
此快照最后确认于
2025/11/23 13:13
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = LLONG_MAX;
int n, m, x, y, matched[505], bef[505];
ll dis[505][505], ex[505], ey[505], slack[505], w;
bool vis[505];
void match(int now) {
	int x, y = 0, ty = 0;
	matched[y] = now;
	while (true) {
		x = matched[y];
		ll d = INF;
		vis[y] = true;
		for (int i = 1; i <= n; i++) {
			if (vis[i]) continue;
			if (slack[i] > ex[x] + ey[i] - dis[x][i]) {
				slack[i] = ex[x] + ey[i] - dis[x][i];
				bef[i] = y;
			}
			if (slack[i] < d) {
				d = slack[i];
				ty = i;
			}
		}
		for (int i = 0; i <= n; i++) {
			if (vis[i]) {
				ex[matched[i]] -= d;
				ey[i] += d;
			} else {
				slack[i] -= d;
			}
		}
		y = ty;
		if (!matched[y]) break;
	}
	while (y) {
		matched[y] = matched[bef[y]];
		y = bef[y];
	}
}
ll KM() {
	for (int i = 1; i <= n; i++) {
		memset(vis, false, sizeof vis);
		for (int j = 1; j <= n; j++) slack[j] = INF;
        memset(bef, 0, sizeof bef);
		match(i);
	}
	ll res = 0;
	for (int i = 1; i <= n; i++)
		if (matched[i])
			res += dis[matched[i]][i];
	return res;
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        ey[i] = -INF;
        for (int j = 1; j <= n; j++) dis[i][j] = -INF;
    }
    for (int i = 1; i <= m; i++) {
        scanf("%d%d%lld", &x, &y, &w);
        dis[x][y] = max(dis[x][y], w);
        ex[x] = max(ex[x], dis[x][y]);
    }
    printf("%lld\n", KM());
    for (int i = 1; i <= n; i++) printf("%d ", matched[i]);
    return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...