0
点赞
收藏
分享

微信扫一扫

根能抵达的点(暑假每日一题 47)


给定一棵由

节点编号从 ,其中

最初,从根节点可以抵达所有节点(包括自己)。

如果我们将所有边权小于

现在,给定一个整数 ,请你找到最小的非负整数 ,使得所有边权小于 的边都被删掉以后,根节点能够抵达的节点数目(包括自己)不超过

输入格式
第一行包含整数 ,表示共有

每组数据第一行包含两个整数

接下来 行,每行包含三个整数 ,表示点 和点 之间存在一条权值为

输出格式
每组数据输出一行,一个

注意, 应不小于

数据范围





保证在一个测试点中,所有 的和不超过

输入样例:

2
3 2
0 1 2
0 2 3
6 3
0 1 8
0 2 3
1 3 2
1 4 5
2 5 6

输出样例:

3
4

#include<iostream>
#include<cstring>

using namespace std;

const int N = 20010, M = 2 * N;

int n;
int h[N], e[M], ne[M], w[M], idx;

void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

int dfs(int u, int pre, int x){

int res = 1;
for(int i = h[u]; ~i; i = ne[i]){

int v = e[i];
if(v == pre) continue;
if(w[i] >= x) res += dfs(v, u, x);
}

return res;
}

int main(){

int t;
scanf("%d", &t);

while(t--){

memset(h, -1, sizeof h);
idx = 0;

int y;
scanf("%d%d", &n, &y);

int a, b, c;
for(int i = 0; i < n - 1; i++){

scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}

int l = 0, r = 2e7;
while(l < r){

int mid = (l + r) >> 1;
int res = dfs(0, 0, mid);
if(res > y) l = mid + 1;
else r = mid;
}

printf("%d\n", l);
}

return 0;
}


举报

相关推荐

0 条评论