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;
}
原文地址:https://www.cnblogs.com/zgglj-com/p/9738886.html