HDU 1281 棋盘游戏(二分图匹配)

题目链接

解题思路

  因为每行每列只能放一个棋子,所以这就是一个匹配问题,每一行最多就只能匹配一列。题目问那些棋子去掉之后最大匹配数会变少,直接枚举就行了。

代码

vector<int> e[maxn], re[maxn];
int deep[maxn], sz[maxn], rec[maxn];
ll sum; 
void dfs(int u, int p, int k) {
	++sz[u]; deep[u] = k;
	for (auto v : e[u])
		if (v!=p) {
			dfs(v, u, k+1);
			sz[u] += sz[v];
		}
	sum += sz[u];
}
ll dfs2(int u, int p) {
	if (rec[u]) return rec[u];
	ll res = 0;
	for (auto v : re[u])
		if (v!=p) res += dfs2(v, u);
	return rec[u] = res + sz[u];
}
int main() {
	int t; scanf("%d", &t);
	while(t--) {
		int n; scanf("%d", &n);
		if (n==1) {
			printf("1
"); continue;
		}
		for (int i = 2, a; i<=n; ++i) {
			scanf("%d", &a);
			e[a].push_back(i);
			re[i].push_back(a);
		}
		sum = 0;
		dfs(1, -1, 1);
		ll ans = -1;
		for (int i = 2; i<=n; ++i) {
			ll k = dfs2(i, -1); ans = max(ans, sum+(ll)deep[i]*n-k);
		}
		printf("%lld
", ans);
		for (int i = 0; i<=n; ++i) {
			e[i].clear(); re[i].clear(); deep[i] = 0; sz[i] = 0; rec[i] = 0; 
		}
	}
    return 0;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/13526277.html