Codeforces Round #635 (Div. 2) C - Linova and Kingdom(樹形dp+思維)

Linova and Kingdom

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Writing light novels is the most important thing in Linova's life. Last night, Linova dreamed about a fantastic kingdom. She began to write a light novel for the kingdom as soon as she woke up, and of course, she is the queen of it.

df63f4ac458c231c1258e895434dcb4c2f090f09.pnguploading.4e448015.gif轉存失敗重新上傳取消df63f4ac458c231c1258e895434dcb4c2f090f09.pnguploading.4e448015.gif正在上傳…重新上傳取消df63f4ac458c231c1258e895434dcb4c2f090f09.pnguploading.4e448015.gif轉存失敗重新上傳取消

 

There are nn cities and n−1n−1 two-way roads connecting pairs of cities in the kingdom. From any city, you can reach any other city by walking through some roads. The cities are numbered from 11 to nn, and the city 11 is the capital of the kingdom. So, the kingdom has a tree structure.

As the queen, Linova plans to choose exactly kk cities developing industry, while the other cities will develop tourism. The capital also can be either industrial or tourism city.

A meeting is held in the capital once a year. To attend the meeting, each industry city sends an envoy. All envoys will follow the shortest path from the departure city to the capital (which is unique).

Traveling in tourism cities is pleasant. For each envoy, his happiness is equal to the number of tourism cities on his path.

In order to be a queen loved by people, Linova wants to choose kk cities which can maximize the sum of happinesses of all envoys. Can you calculate the maximum sum for her?

Input

The first line contains two integers nn and kk (2≤n≤2⋅1052≤n≤2⋅105, 1≤k<n1≤k<n)  — the number of cities and industry cities respectively.

Each of the next n−1n−1 lines contains two integers uu and vv (1≤u,v≤n1≤u,v≤n), denoting there is a road connecting city uu and city vv.

It is guaranteed that from any city, you can reach any other city by the roads.

Output

Print the only line containing a single integer  — the maximum possible sum of happinesses of all envoys.

Examples

input

7 4
1 2
1 3
1 4
3 5
3 6
4 7

output

7

input

4 1
1 2
1 3
2 4

output

2

input

8 5
7 5
1 7
6 1
3 7
8 3
2 1
4 5

output

9

Note

In the first example, Linova can choose cities 22, 55, 66, 77 to develop industry, then the happiness of the envoy from city 22 is 11, the happiness of envoys from cities 55, 66, 77 is 22. The sum of happinesses is 77, and it can be proved to be the maximum one.

In the second example, choosing cities 33, 44 developing industry can reach a sum of 33, but remember that Linova plans to choose exactly kk cities developing industry, then the maximum sum is 22.

題意:

給你一顆n(<=2e5)個節點的無向樹,其中1爲根,你要選擇恰好k個結點染色,使得這k個點到根的路徑中每個點經過的未染色點的數量之和最大。

思路:感覺這題比同場的D更難一些。首先就是題意有些迷,剛開始讀成了選k個點,使得這k個點到根節點的路徑長度之和最大。一想這不就是求深度最大的k個點嗎?然後樣例第三組就過不去。。。

實際上思路差不多。我們依然從深度最大的點開始選,如果是葉節點,那麼就直接選,貢獻就是該節點到根節點的距離,否則這個節點的貢獻就是 該節點到根節點的距離-該節點爲根的子樹的大小+1(因爲每個孩子節點在父節點被選之前一定全都被選了,一旦選擇父節點,所有孩子節點經過的未染色點就會都減少一個)

我一共WA了三發:①讀錯題意②答案在計算到某一步的時候可能開始減少③每個非葉子節點都會改變且只改變一次自己對答案的貢獻

代碼:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=4e5+5;
//const double pi=acos(-1.0);
//const double eps=1e-9;
//const ll mo=1e9+7;
int n,m,k,q;
int fa[maxn],dp[maxn];
int ans,tmp,cnt;
int flag;
int ok[maxn];
vector<int>vc[maxn],a[maxn];
void dfs(int u,int f,int dep){
    a[dep+n].push_back(u);
    dp[u]=1;fa[u]=f;
    for(int i=0;i<vc[u].size();i++){
        int v=vc[u][i];
        if(v==f) continue;
        dfs(v,u,dep+1);
        dp[u]+=dp[v];
    }
}
int main()
{
    int T,cas=1;
    //scanf("%d",&T);
    //while(T--)
    {
        scanf("%d%d",&n,&k);
        rep(i,1,n-1){
            int x,y;
            scanf("%d%d",&x,&y);
            vc[x].push_back(y);
            vc[y].push_back(x);
        }
        dfs(1,0,0);
        ll ans=0;
        dep(i,2*n,0) if(a[i].size()&&k>0){
            for(int j=0;j<a[i].size();j++){
                int v=a[i][j];
                if(k<=0) break;
                if((dp[v]==1)||(ok[v])) {
                    ans+=i-n;k--;
                    //cout<<v<<" "<<ans<<" "<<k<<endl;
                }
                else {
                    //cout<<v<<" "<<i-dp[v]+1<<endl;
                    a[i-dp[v]+1].push_back(v);ok[v]=1;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章