Linova and Kingdom CodeForces - 1336A (思维)

Posted accepting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linova and Kingdom CodeForces - 1336A (思维)相关的知识,希望对你有一定的参考价值。

题目大意:一棵树,然后选k个点,让每个点到根节点的距离之和最大。

题解:求每个点对答案的贡献,假设第i个点的深度为dep,它所具有的子树的大小为tmp,那么他对答案的贡献为dep-tmp,为什么是这样呢?当我们选了一个点c的时候,那么他的子节点一定都被选过了,因为如果没有选过的话,我们完全可以选择它的子节点,这样会更有一点,所以dfs求每个点的深度个每个点的子树节点的数目,然后排序一下就好了。

code:

  

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+7;
ll dis[N];//每个点所具有的子节点个数
ll dp[N];//每个点的深度 
bool mark[N];
ll arr[N];
vector<ll>ve[N];
ll dfs(ll x,ll cnt){
    mark[x]=1;
    ll tmp=1;
    for(ll i=0;i<ve[x].size();i++){
        if(!mark[ve[x][i]]) {
            tmp+=dfs(ve[x][i],cnt+1);
        }
    }
    dp[x]=cnt;
    return dis[x]=tmp;
}
bool cmp(const ll x,const ll y){
    return x>y;
}
int main(){
    ll n,k;
    cin>>n>>k;
    ll x,y;
    for(ll i=1;i<n;i++){
        cin>>x>>y;
        ve[x].push_back(y);
        ve[y].push_back(x);
    }
    dfs(1,1);
    for(ll i=1;i<=n;i++){
        arr[i]=dp[i]-dis[i];
    }
    sort(arr+1,arr+1+n,cmp);
    ll ans=0;
    for(ll i=1;i<=k;i++){
        ans+=arr[i];
    }
    cout<<ans<<endl;  
    return 0;
} 

 

以上是关于Linova and Kingdom CodeForces - 1336A (思维)的主要内容,如果未能解决你的问题,请参考以下文章

CF1336 Linova and Kingdom

Linova and Kingdom CodeForces - 1336A

Linova and Kingdom CodeForces - 1336A

Linova and Kingdom CodeForces - 1336A (思维)

Linova and Kingdom CodeForces - 1336A (思维)

Codeforces 1337C - Linova and Kingdom(树/DFS/BFS/贪心)