列表

详情


NC23865. Chino with Triangle

描述

Chino的数学很差,因此Cocoa非常担心。今天,Cocoa要教Chino和三角形有关的知识。
众所周知,,它们能构成三角形的条件是.
另一个众所周知的事实是,“树”是一种包含了个点和n-1条边的连通无向无环图。因此,树上两点之间的简单路径是唯一确定的,也就是说,两点之间的距离是唯一确定的。
现在,Cocoa想要知道,完全随机地从树上取三个点u,v,w,得到三个距离,这三个距离构成三角形的概率是多少?
题目对Chino来说太难啦,你能帮一帮Chino吗?

输入描述

第一行是一个正整数n;接下来n-1行每行两个数u, v,描述了一条长度是1的无向边

输出描述

题目中要求的答案。你的答案会被认为是正确的,当且仅当你的答案是a,标准答案是b,并且

示例1

输入:

4
1 2
1 3
1 4

输出:

0.250000000000

说明:

显然只有(2, 3, 4)是可以的

示例2

输入:

6
1 2
1 3
2 4
2 5
5 6

输出:

0.200000000000

原站题解

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

C++14(g++5.4) 解法, 执行用时: 127ms, 内存消耗: 7296K, 提交时间: 2020-01-10 12:30:04

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,dp[N],sz[N],res,tot;
vector<int> g[N];
void dfs(int x,int fa){
	sz[x]=1;	int sum=0;
	for(int i=0;i<g[x].size();i++){
		int to=g[x][i];	if(to==fa)	continue;
		dfs(to,x);	res+=sum*sz[to];
		sum+=sz[to];	sz[x]+=sz[to];
	}
	res+=(n-sz[x])*(sz[x]-1);
}
signed main(){
	cin>>n;
	for(int i=1,a,b;i<n;i++)	
		scanf("%lld %lld",&a,&b),g[a].push_back(b),g[b].push_back(a);
	dfs(1,1);	tot=n*(n-1)*(n-2)/6;
	printf("%.8lf\n",(double)(tot-res)/tot);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 84ms, 内存消耗: 6496K, 提交时间: 2020-03-17 16:56:17

#include<bits/stdc++.h>
using namespace std;
vector<int>g[100005];
long long ans;
int d[100005],n;
void dfs(int u,int fa)
{
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)
		continue;
		dfs(v,u);
		ans+=1ll*d[u]*d[v];
		d[u]+=d[v]; 
	}
	d[u]++;
	ans+=1ll*(d[u]-1)*(n-d[u]);
}
int main()
{
	scanf("%d",&n);
	int u,v;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	ans=0;
	dfs(1,0);
	long long m=1ll*n*(n-1)*(n-2)/6;
	double s=ans/(double)m;
	printf("%.12lf\n",1.0-s);
}

上一题