CF1689C 题解
思路
这题的舍取我们可以分情况考虑:
- 是叶子结点,删不删无所谓,都是 ;
- 有一个儿子,果断删,保全它的所有子节点,共 个(其中 表示以 为根的子树下的节点个数);
- 有两个儿子,只能舍一个保一个,保左儿子和保右儿子取个 就行。舍的部分继续递归。
代码
# include <bits/stdc++.h>
using namespace std;
int t, n, x, y, s[300005];
vector <int> v[300005];
int sum (int x, int f) {
if (s[x])
return s[x];
s[x] = 1;
for (int i : v[x])
if (i != f)
s[x] += sum (i, x);
return s[x];
}
int fun (int x, int f) {
int l = 0, r = 0;
for (int i : v[x])
if (i != f)
if (l)
r = i;
else
l = i;
if (r)
return max (fun (l, x) + sum (r, x), sum (l, x) + fun (r, x)) - 1;
if (l)
return sum (l, x) - 1;
return 0;
}
int main () {
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
cin >> t;
while (t --) {
cin >> n;
for (int i = 1; i <= n; ++ i)
v[i].clear (), s[i] = 0;
while (-- n)
cin >> x >> y, v[x].push_back (y), v[y].push_back (x);
cout << fun (1, 0) << '\n';
}
return 0;
}

浙公网安备 33010602011771号