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\n"); 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\n", 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;
}