给定一棵由
节点编号从 到
,其中
最初,从根节点可以抵达所有节点(包括自己)。
如果我们将所有边权小于
现在,给定一个整数 ,请你找到最小的非负整数
,使得所有边权小于
的边都被删掉以后,根节点能够抵达的节点数目(包括自己)不超过
。
输入格式
第一行包含整数 ,表示共有
每组数据第一行包含两个整数 。
接下来 行,每行包含三个整数
,表示点
和点
之间存在一条权值为
输出格式
每组数据输出一行,一个 。
注意, 应不小于
。
数据范围
保证在一个测试点中,所有 的和不超过
。
输入样例:
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;
}