Codeforces Round #633 (Div. 1)
A
略
B
答案最大为 (3)。如果用 (2) 种,那一定可以只用 (1) 种。然后看看什么情况只用 (1) 种(略)
C
找规律(略)
D
设选出的集合为 (S),则 (forall u),以 (u) 为根,除了 (u) 的儿子外,至多在 (u) 的两个儿子子树中有 (S) 的点。证明要画个图,就粘一个吧(wucstdio)
这个性质说明:可以找到一条链,(forall xin S),(x) 在链上或与链相邻。然后,(S) 中的点显然不能相邻。根据这两个限制来搞一个树形 (dp) 。(f_{i,0/1}) 表示第 (i) 个点选不选的最大答案,至于转移,。。。
const int N = 1e5 + 5;
int n, res, c[N], f[N][2]; vector<int> g[N];
#define pb push_back
void add (int u, int v) {
g[u].pb (v), g[v].pb (u), ++c[u], ++c[v];
}
void Max (int &x, const int y) { if (y > x) x = y; }
void dp (int u, int la) {
f[u][1] = 1;
for (int v : g[u]) if (v != la) {
dp (v, u);
int t = max (f[v][0], f[v][1]);
Max (res, f[u][0] + t);
Max (res, f[u][1] + f[v][0]);
Max (f[u][0], t + c[u] - 2);
Max (f[u][1], f[v][0] + 1);
}
Max (res, f[u][1]);
}
signed main() {
read (n);
for (int i = 1, u, v; i < n; ++i)
read (u), read (v), add (u, v);
dp (1, 0); printf ("%d
", res);
return 0;
}