Codeforces 980E The Number Games (贪心 + 倍增)

本文介绍了Codeforces上的一道题目980E,即The Number Games。题目背景设定在一个国家的年度比赛,总统打算淘汰一部分选手以降低成本。解题关键在于确保剩余选手的所在区域相互可达,并最大化粉丝总数。通过贪心策略和考虑路径连通性,可以确定应淘汰的选手所属地区。样例输入和输出展示了具体的操作过程。
摘要由CSDN通过智能技术生成

任重而道远

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 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

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

Output

1 3 4

Input

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

Output

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.

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N = 1e6 + 7, P = 22;
struct Edge {
	int tov, nxt;
}e[N << 1];
int n, k, num, sww;
int anc[N][P + 3], vis[N], head[N];

void add_edge (int u, int v) {
	e[++num] = (Edge) {v, head[u]}, head[u] = num;
}

void dfs (int u, int fa) {
	anc[u][0] = fa;
	for (int p = 1; p <= P; p++)
		anc[u][p] = anc[anc[u][p - 1]][p - 1];
	for (int i = head[u]; i; i = e[i].nxt) {
		int v = e[i].tov;
		if (v == fa) continue;
		dfs (v, u);
	}
}

int check (int u, int tot) {
	for (int p = P; p >= 0; p--)
		if (!vis[anc[u][p]]) {
			tot -= (1 << p);
			u = anc[u][p];
		}
	return tot >= 1;
}

int main () {
	scanf ("%d%d", &n, &k);
	for (int i = 1; i < n; i++) {
		int u, v;
		scanf ("%d%d", &u, &v);
		add_edge (u, v), add_edge (v, u);
	}
	dfs (n, n);
	vis[n] = 1;
	sww = n - k - 1;
	for (int i = n - 1; i >= 1; i--)
		if (check (i, sww)) {
			int u = i;
			while (!vis[u]) {
				vis[u] = 1;
				u = anc[u][0];
				sww--;
			}
		}
	for (int i = 1; i <= n; i++) if (!vis[i]) printf ("%d ", i);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值