hdu2376 Average distance (樹形dp)
阿新 • • 發佈:2018-10-31
這題主要是求任意兩點之間的距離之和。首先通過列舉起點終點來求的話是O(N^2),會超時的,這題要換種思路,通過算每條邊的貢獻來得到任意兩點之間的距離之和,每條邊的貢獻就是其2端的點數的乘積再乘以對應的邊權,求每條邊2端的點數就用dfs即可。
#include<bits/stdc++.h> using namespace std; const int maxn=1e4+10; #define ll long long struct node { int v; ll w; node(int vv,ll ww) { v=vv; w=ww; } }; vector<node>g[maxn]; ll ans,num[maxn];//num[i]表示子樹i對應的節點的個數 int n; void dfs(int now,int fa) { num[now]=1; for(int i=0;i<g[now].size();i++) { int v=g[now][i].v; ll w=g[now][i].w; if(v==fa) continue; dfs(v,now); num[now]+=num[v]; ans+=w*(n-num[v])*num[v]; } } int main() { int t; scanf("%d",&t); while(t--) { ans=0; scanf("%d",&n); for(int i=0;i<n;i++) g[i].clear(),num[i]=0; for(int i=1;i<=n-1;i++) { int u,v; ll w; scanf("%d %d %lld",&u,&v,&w); g[u].push_back(node(v,w)); g[v].push_back(node(u,w)); } dfs(0,-1); int tmp=n*(n-1)/2; printf("%.6lf\n",ans*1.0/tmp); } return 0; }