题目链接:
http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=704分析:
点数最大为100000,所以最小生成树应该用Kruskal。因为任意两点的距离不相等,所以最小生成树唯一,那么期望也就是唯一的。而这个期望即任意两点距离的平均值。我们先统计出每条边在所有路径中被用到的次数,用它乘以这条边的权重,加在一块然后除以总路径数(n×(n-1)/2)就能得到结果。题解:
- 在kruskal的取边操作里,如果某条边符合条件被选中,这时候加一个操作,把这条边记录到数组里(一条边从两个方向要被记录两次),然后用一个add函数将每条边加入到新的结构体里面,这个结构体的序号是边的序号,里面存储这条边的下一个节点,以及这个边的权重,然后记录这条边的下一条边的序号。
DFS函数:任取一个点作为根节点开始搜索,对每个点i记录其子树包含的点数(包括其自身),设点数为sum[i],则i的父亲一侧的点数即为n-sum[i]。两者相乘就是这条边被用到的次数,边遍历边统计。
- P.S. :此处DFS以及add函数的详细分析可以参考 树形DP中的DFS函数与head数组。
DFS 代码:
- P.S. :此处DFS以及add函数的详细分析可以参考 树形DP中的DFS函数与head数组。
struct edge
{
int from,to,w,next;
}e[1000050];
void add(int from,int to,int w)
{
e[cont].to=to;
e[cont].w=w;
e[cont].next=head[from];
head[from]=cont++;
}
ll Dfs(int u)
{