CodeForces - 980E The Number Games(贪心+树上倍增)

版权声明:Why is everything so heavy? https://blog.csdn.net/lzc504603913/article/details/82971047

E. The Number Games

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The nation of Panel holds an annual show called The Number Games, where each district in the nation will be represented by one contestant.

The nation has nn districts numbered from 11 to nn, each district has exactly one path connecting it to every other district. The number of fans of a contestant from district ii is equal to 2i2i.

This year, the president decided to reduce the costs. He wants to remove kk contestants from the games. However, the districts of the removed contestants will be furious and will not allow anyone to cross through their districts.

The president wants to ensure that all remaining contestants are from districts that can be reached from one another. He also wishes to maximize the total number of fans of the participating contestants.

Which contestants should the president remove?

Input

The first line of input contains two integers nn and kk (1≤k<n≤1061≤k<n≤106) — the number of districts in Panel, and the number of contestants the president wishes to remove, respectively.

The next n−1n−1 lines each contains two integers aa and bb (1≤a,b≤n1≤a,b≤n, a≠ba≠b), that describe a road that connects two different districts aaand bb in the nation. It is guaranteed that there is exactly one path between every two districts.

Output

Print kk space-separated integers: the numbers of the districts of which the contestants should be removed, in increasing order of district number.

Examples

input

Copy

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

output

Copy

1 3 4

input

Copy

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

output

Copy

1 3 4 5

Note

In the first sample, the maximum possible total number of fans is 22+25+26=10022+25+26=100. We can achieve it by removing the contestants of the districts 1, 3, and 4.

题意:给你一棵树,树上的点的权值为2^i,问你保留K个点,使得保留的点都是联通的,并且点权和最大。

解题思路:明显贪心,肯定是先从N开始取,一直取到1,,所以对于每一个点,我们贪心的取,如何保证联通呢?暴力的查找离他最近的已经被取的点,因为我们先取N,那就以N为根,那么就变成了暴力往上走,遇到的第一个已经取的点的时候经过的点都要取。这里暴力往上走然后取点就好了。但是,我们有K限制,所以暴力往上走可能会超过了K,那么就白走了,所以我们先用倍增判断往上走是否可行,不可行的话直接下一个点。

#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
#include <set>
#include <stdio.h>
#include <map>
#include <bitset>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN = 2000005;

int N,K;
vector<int> G[MAXN];
int fa[20][MAXN];
void dfs(int u,int pre){
    fa[0][u]=pre;
    for(int i=1;i<20;i++)
        fa[i][u]=fa[i-1][fa[i-1][u]];
    for(int i=0;i<G[u].size();i++){
        if(G[u][i]!=pre)
            dfs(G[u][i],u);
    }
}

bool vis[MAXN];

int main()
{

    scanf("%d%d",&N,&K);
    int u,v;
    for(int i=0;i<N-1;i++){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    dfs(N,N);

    K=N-K-1;
    vis[N]=1;

    for(int i=N-1;i>=1;i--){

        if(vis[i])
            continue;

        int tmp=i;
        int sum=0;

        for(int j=19;j>=0;j--){
            if(!vis[fa[j][tmp]]){
                tmp=fa[j][tmp];
                sum+=(1<<j);
            }
        }
        sum++;
        if(sum<=K){
          K-=sum;
          tmp=i;
          while(!vis[tmp]){
              vis[tmp]=1;
              tmp=fa[0][tmp];
          }
        }

    }

    for(int i=1;i<=N;i++)
        if(!vis[i])
            printf("%d ",i);





    return 0;
}










猜你喜欢

转载自blog.csdn.net/lzc504603913/article/details/82971047
今日推荐