HDU 2376 Average distance (树形dp)


Average distance

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 588    Accepted Submission(s): 213

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:
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
 
Source
bapc2007

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2376

题目大意:一棵树,求任意两点间的平均距离

题目分析:先求出任意两点间的距离和,再除总边数(这里的边指的是任意两点间的直接路径数 n * (n - 1) / 2),求和显然没能枚举,我们可以发现一条路径被经过的次数为其左边点数*右边点数,所以根据这个我们可以算出每条边对总值的贡献,树形dp求一下即可


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e4 + 5;
int n, cnt, head[MAX], num[MAX];
double sum;

struct EDGE
{
	int v, w, next;
}e[2 * MAX];

void Add(int u, int v, int w)
{
	e[cnt].v = v;
	e[cnt].w = w;
	e[cnt].next = head[u];
	head[u] = cnt ++;
}

void DFS(int u, int fa)
{
	num[u] = 1;
	for(int i = head[u]; i != -1; i = e[i].next)
	{	
		int v = e[i].v;
		int w = e[i].w;
		if(v != fa)
		{
			DFS(v, u);
			num[u] += num[v];
			sum += 1.0 * num[v] * (n - num[v]) * w;
		}
	}
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T --)
	{
		cnt = 0;
		sum = 0;
		memset(head, -1, sizeof(head));
		scanf("%d", &n);
		for(int i = 0; i < n - 1; i++)
		{
			int u, v, w;
			scanf("%d %d %d", &u, &v, &w);
			Add(u, v, w);
			Add(v, u, w);
		}
		DFS(0, -1);
		printf("%.7f\n", sum / (1.0 * n * (n - 1) / 2.0));
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值