1. 程式人生 > >HDU——2376 Average distance (樹形dp)

HDU——2376 Average distance (樹形dp)

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. 

 

Input

On 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. 
 

Output

For 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

題意:就是求上面那個式子的值,看式子和圖就能懂。

題解:用樹形dp跑,把每條邊用的次數算出來,然後乘這條邊的值就好了,用過的次數=該邊的尾節點後邊所連點的個數(包括該點)*該邊的尾節點前面所連點的個數(不包括該點),然後用次數乘價值,最後把每條邊所求加和,就可以了。

注意:不能用cin,cout 輸入輸出流,要用標準輸入,輸出,要不然會T(超時)。  上程式碼:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX = 1e5;
struct hh{
	int u,v;
	double w;
	int nt;
}a[MAX];//用來儲存樹
int head[MAX];
double num[MAX];
int cnt,n;
double ar;
void add(int u,int v,double w){//建樹,記住就好了
	a[cnt].u=u;
	a[cnt].v=v;
	a[cnt].w=w;
	a[cnt].nt=head[u];
	head[u]=cnt++;
}
void dfs(int foot,int fz){
	num[foot]=1;
	for (int i = head[foot]; ~i; i = a[i].nt){
		int vv=a[i].v;
		int ww=a[i].w;
		if(vv!=fz){
			dfs(vv,foot);
			num[foot]+=num[vv];//統計用的次數
			ar+=num[vv]*(n-num[vv])*ww;//後邊*前邊*價值,然後相加
		}
	}
} 
int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		memset(head,-1,sizeof(head));//存為-1,建圖常用
		memset(num,0,sizeof(num));//初始化
		cnt=0;
		scanf("%d",&n);
		for (int i = 0; i < n-1;i++){
			int u,v;
			double w;
			scanf("%d%d%lf",&u,&v,&w);
			add(u,v,w);//建立雙向 ,看題目裡的圖就知道
			add(v,u,w);
		}
		ar=0;
		dfs(0,-1);
		printf("%.7f\n",ar/(1.0*n*(n-1)/2.0));//輸出注意精度
	}	
	return 0;
}