Average distance
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 (d 01 + d 02 + d 03 + d 04 + d 12 +d 13 +d 14 +d 23 +d 24 +d 34)/10 = (6+3+7+9+9+13+15+10+12+2)/10 = 8.6.
InputOn the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:
One line with an integer n (2 <= n <= 10 000): the number of nodes in the tree. The nodes are numbered from 0 to n - 1.
n - 1 lines, each with three integers a (0 <= a < n), b (0 <= b < n) and d (1 <= d <= 1 000). There is an edge between the nodes with numbers a and b of length d. The resulting graph will be a tree.
OutputFor each testcase:
One line with the average distance between two vertices. This value should have either an absolute or a relative error of at most 10 -6
Sample Input
1 5 0 1 6 0 2 3 0 3 7 3 4 2
Sample Output
8.6题意:求一个树上任意两点距离的平均值。其实也不算是一棵树,因为节点之间都是双向边。思路: 对于每一条边,计算一下它两端的节点数A,B,那么每一条边的权值*左边的节点数*右边的节点数就是该条边的被经过的次数累加的贡献。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1e5+10; 9 struct node{ 10 int v; 11 ll w; 12 }now; 13 vector<node>v[maxn]; 14 int vis[maxn]; 15 int n,a,b; 16 ll w,ans,t,son[maxn]; 17 void dfs(int x) 18 { 19 vis[x]=1; 20 son[x]=1; 21 for(int i=0;i<v[x].size();i++) 22 { 23 node aa=v[x][i]; 24 ll len=aa.w; 25 int to=aa.v; 26 if(vis[to]) 27 continue; 28 dfs(to); 29 son[x]+=son[to]; 30 ans+=len*(n-son[to])*son[to]; //注意2:这里一定要写son[to]而不是son[x] 写son[x]会导致边和其两边的点数不匹配。 31 // cout<<x<<" "<<to<<endl; 32 cout<<ans<<endl; 33 } 34 } 35 int main() 36 { 37 int casen; 38 cin>>casen; 39 while(casen--) 40 { 41 ans=0; 42 memset(son,0,sizeof(son)); 43 memset(vis,0,sizeof(vis)); 44 scanf("%d",&n); 45 for(int i=0;i<=n;i++) 46 v[i].clear(); 47 for(int i=1;i<n;i++) 48 { 49 scanf("%d%d%lld",&a,&b,&w); 50 now.v=b; 51 now.w=w; 52 v[a].push_back(now); 53 now.v=a; //注意1:双向边对于该边的两个端点都要标记权值为边的值,这样不管先遍历到哪个节点,这个节点的权值就是该点和其下一个点之间的边的权值。 54 v[b].push_back(now); 55 } 56 dfs(0); 57 t=(n-1)*n/2; 58 printf("%.11f\n",(double)ans/(double)t);//注意3: 题目好坑啊,要求的误差在10-6 但是样例给的只是小数点后一位。 59 } 60 }
原文地址:https://www.cnblogs.com/1013star/p/9959873.html