Average distanceTime Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1266 Accepted Submission(s): 456 Special Judge Problem Description Given a tree, calculate the average distance between two vertices in the tree. For example, the average distance between two vertices in the following tree is (d01 + d02 + d03 + d04 + d12 +d13 +d14 +d23 +d24 +d34)/10 = (6+3+7+9+9+13+15+10+12+2)/10 = 8.6.
Input On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:
Output For each testcase:
Sample Input 1 5 0 1 6 0 2 3 0 3 7 3 4 2
Sample Output 8.6 |
题意:
给你一棵树和边的权值,要你求树上两两距离的平均和。
做法:
树形dp求。因为如果枚举任意两个点肯定会T,所以不如求每个边的贡献次数乘上距离,最后除总路径。每个边的贡献次数等于该边两端顶点个数的积,所以这题就是求每个顶点子树的节点个数。只用做一次dfs就好,dfs写法见代码。最后注意要用long long 。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=100005;
struct node{
int to,next;
ll w;
}e[maxn<<1];
int n,head[maxn],cnt,sz[maxn];
ll fac[maxn];
ll dp[maxn];
void add(int u,int v,ll w){
e[cnt].to=v,e[cnt].next=head[u];
e[cnt].w=w,head[u]=cnt++;
}
void dfs(int x,int fa){
sz[x]=1;
for(int i=head[x];~i;i=e[i].next){
int t=e[i].to,w=e[i].w;
if(fa==t) continue;
dfs(t,x);
sz[x]+=sz[t];
dp[x]=(dp[x]+dp[t]+(double)(n-sz[t])*sz[t]*w);
}
}
int main(){
int x,y,t;
ll w;
cin>>t;
while(t--){
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
cnt=0;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%lld",&x,&y,&w);
x++,y++;
add(x,y,w);
add(y,x,w);
}
dfs(1,-1);
double s=n*(n-1);
printf("%.11f\n",((double)dp[1])*2.0/s);
}
return 0;
}