Codeforces Round #635 (Div. 2) C. Linova and Kingdom题解

发布于 2020-04-17  0 次阅读


思路:

贪心,如果选择某个节点 i 作为旅游城市,那么对增加的度就是以节点 i 为根的子树(不包括节点 i )包含的节点数量对减少的度就是节点 i 的所有祖先节点中的旅游城市数量。
所以每个节点对答案的贡献就可以转化成 以节点 i 为根的子树(不包括节点 i )包含的节点数量 - 节点 i 的祖先节点数量。

AC Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> G[200009];
bool vis[200009];

struct node{
    int child, dis; // child存子节点个数,dis为深度
    bool operator< (const node& a)const{
        return child-dis>a.child-a.dis;
    }
}ar[200009];

int dfs(int pos, int f)
{
    vis[pos]=true;
    ar[pos].dis=ar[f].dis+1;
    for(int it: G[pos])                    //遍历vector求子节点个数
        if(!vis[it])
            ar[pos].child+=dfs(it,pos);
    return ar[pos].child+1;
}

int main()
{
    int n, k, a, b;
    cin>>n>>k;
    for(int i=1; i<n; i++)
    {
        cin>>a>>b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    ar[0].dis=-1;
    dfs(1,0);
    sort(ar+1,ar+n+1);
    ll ans=0;
    for(int i=1; i<=n-k; i++)
    {
        ans+=ar[i].child-ar[i].dis;
    }
    cout<<ans<<endl;
    return 0;
}

平平无奇的在校大学生