题目大意:给你一棵树,让你分配边权,使树的直径最小。(我们把加权树的直径定义为两个叶子节点之间路径上的权值的最大和)
题解:树的一条直径一定要经过两个叶子节点,要使得直径最小,只需要让所有连接叶子节点的边平分所有权值即可,注意精度。叶子节点的度为1,所以找到度为1的所有的点即可。用数组记录每个节点的度,每加入一个边,两点的度分别加一。
#include<bits/stdc++.h>
using namespace std;
double n, s;
int tree[200010];
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> s;
for (int i = 1; i <= n; i++) {
tree[i] = 0;
}
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
tree[a]++; tree[b]++;
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (tree[i] == 1)ans++;
}
printf("%.8lf",s/ans*2);
return 0;
}