列表

详情


NC220367. H有多短

描述

给定一棵n(2<=n<=100000,n∈Z+)个点的树(保证树连通),将k(0<=k<=1000000000,k∈Z)分配到各个边的权值上,使得每条边权值为A[i](0<=A[i]<=k,A[i] ∈ R)。现求分配权值后树的直径的最小值。

树的直径:树上最远的两点的路径权值和。




输入描述

n k

接下来的n-1行,每行包括u和v,表示结点u和v相连

2<=n<=100000,n∈Z+

0<=k<=1000000000,k∈Z

1<=u, v<=n, f[i] ∈ Z


输出描述

分配权值后树的直径的最小值,保留6位小数

示例1

输入:

2 10
1 2

输出:

10.000000

说明:

最短情况也是唯一情况,1-2这条边赋予权值10,直径为10

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C(clang11) 解法, 执行用时: 30ms, 内存消耗: 632K, 提交时间: 2021-03-28 10:45:37

#include<stdio.h>
int d[100002],n,k;
int main() {
	scanf("%d%d",&n,&k);
	double num =0 ;
	for(int i=1; i<=n-1 ; i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		d[u]++,d[v]++;
	}
	for(int i=1 ; i<=n ; i++) if(d[i]==1) num = num+1;
	double ans = 1.0*k/num*1.0;
	printf("%.6lf",ans*2.0);

	return 0;
}

C++(clang++11) 解法, 执行用时: 49ms, 内存消耗: 760K, 提交时间: 2021-03-30 15:16:00

#include<bits/stdc++.h>
using namespace std;
int n,s,x,y,rd[100005];
double k;
int main()
{
	cin>>n>>k;
	for(int i=1;i<n;i++)
	{
		cin>>x>>y;
		rd[x]++; rd[y]++;
	}
	for(int i=1;i<=n;i++)
	    if(rd[i]==1) s++;
	printf("%.6f",2.0*k/s);
	return 0;
}

上一题