Tree
题意
给一棵\(n\)个结点的树,和\(k\)种颜色,用给的颜色去给每个结点染色,然后将相同颜色的点连通所需要的最少的边作为一个集合。因为有\(k\)种颜色,所以会形成\(k\)个集合。然后最大化这些集合的交集的大小。
题解
以为是构造,其实就是一个思维题。点不好考虑就考虑枚举边,从答案入手,如果一条边是交集里面的边,现断开这条边,树被分为两颗树,则这两棵树的大小都要大于等于\(k\)才行。因为每棵树都要染上k种颜色,这条边才会出现在交集中。
收获
个人觉得是一个好题,尤其出现在比赛中,如果找到了关键点,就能迎刃而解。有时解题还是要讲究一些技巧的。
代码
const int N = 200005;
int n, k;
int sz[N], d[N];
vector<int> G[N];
void DFS(int u, int p, int dep) {
d[u] = dep;
for (auto v : G[u]) if (v != p) {
DFS(v, u, dep + 1);
sz[u] += sz[v];
}
}
int main()
{
BEGIN(){
sc(n), sc(k);
Rep(i, 1, n) G[i].clear(), sz[i] = 1;
P p[N];
rep(i, 1, n) {
int u, v;
sc(u), sc(v);
G[u].pb(v);
G[v].pb(u);
p[i].first = u;
p[i].second = v;
}
DFS(1, 1, 0);
int ans = 0;
rep(i, 1, n) {
int u = p[i].first;
int v = p[i].second;
if (d[u] > d[v]) swap(u, v);
if (sz[v] >= k && (n - sz[v]) >= k) ans++;
}
pr(ans);
}
return 0;
}