Chino with Triangle

在这里插入图片描述


直接去想怎么是合法的三角形,比较麻烦。如果我们想不合法的三角形,我们可以发现因为距离都是树上的距离,只有三个点在一条链上的时候才是不合法的。否则都是合法的三角形。所以要算出不合法的三角形。
也就是我们要枚举每一条链?怎么枚举呢?

这个就和点分治比较类似了,只不过我们不用点分治这么麻烦,我们直接枚举每个点为三角形中间的点v,其余两个点在不同子树中的答案即可。

AC代码:

#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;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103922474