codeforces980e(倍增、贪心|| 树的dfs序差分+树状数组)

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

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 aa and 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.

题意:给定n个点形成一棵树,序号1~n,每个点的value为2^i,现在要去掉k个点,使得其余的点还是一棵树并且值和最大,求去掉哪些点。

思路:

1、采用topo不能够得到正确答案。我们肯定是要贪心来做,保大。n必须留下作为根节点,再遍历n-1~1这几个节点,如果满足要求则把这个节点及其到根节点的枝都留下,如果不满足要求(要留下的超过了数目)则不留。在遍历一个节点的祖先节点的时候采用倍增预处理。

#include   
using namespace std;  
const int maxn = 1e6 + 100;  
vectortr[maxn];  
int par[maxn];  
int up[22][maxn];  
bool used[maxn];  
void dfs(int u, int fa)  
{  
    par[u] = up[0][u] = fa;  
    for(int i = 1;i<22;i++) 
        up[i][u] = up[i-1][up[i-1][u]];  
    for(int to=0;to=0;j--)
        {
            if(!used[up[j][v]])
            {
                len += (1<

还有一种方法:利用树的dfs序(还是以n为根),可以确定一个节点的子树(前序遍历后序遍历确定),然后通过差分,增加一个节点就在这个节点子树开始位置+1,在子树结束后位置-1,这样对别的子树影响不到。通过树状数组查询可以确定这个节点的祖先节点有几个不用remove。过程还是贪心地取。

代码:http://codeforces.com/contest/980/submission/50068081

你可能感兴趣的:(贪心,数据结构)