zoukankan      html  css  js  c++  java
  • Linova and Kingdom CodeForces

    题目大意:一棵树,然后选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;
    } 
  • 相关阅读:
    AJ学IOS 之ipad开发qq空间项目横竖屏幕适配
    C语言小练习之学生信息管理系统
    014-预处理指令-C语言笔记
    013-结构体-C语言笔记
    012-C语言小游戏之推箱子
    011-指针(上)-C语言笔记
    010-字符串-C语言笔记
    009-数组-C语言笔记
    008-进制-C语言笔记
    007-函数-C语言笔记
  • 原文地址:https://www.cnblogs.com/Accepting/p/12834704.html
Copyright © 2011-2022 走看看