NC23865. Chino with Triangle
描述
Chino的数学很差,因此Cocoa非常担心。今天,Cocoa要教Chino和三角形有关的知识。
众所周知,,它们能构成三角形的条件是.
另一个众所周知的事实是,“树”是一种包含了个点和条边的连通无向无环图。因此,树上两点之间的简单路径是唯一确定的,也就是说,两点之间的距离是唯一确定的。
现在,Cocoa想要知道,完全随机地从树上取三个点,得到三个距离,这三个距离构成三角形的概率是多少?
题目对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); }