引入
现给定一棵n个节点,有边权的树,求其中每个点到其他节点的距离和?
首先考虑暴力算法:从1开始做dfs,1到所有节点的距离之和定义为F[1],再定义节点u到v的距离为D(u,v)则存在如下关系
可以通过一次以1为根的dfs,求出所有的D(i,1),复杂度为O(n)。同理,对每个节点做一次dfs,就可以求得n个节点的结果。此时总的时间复杂度就为O()。
伪代码如下:
void dfs(int now,int father)
{
siz[now]=1;
for(int i=link[now];i;i=edge[i].nxt)
{
if(edge[i].y==father) continue;//不搜索父节点
dfs(edge[i].y,now);
siz[now]+=siz[edge[i].y];
d[now]+=d[edge[i].y]+edge[i].v*siz[edge[i].y];
}
}
但如果数据规模为1n
100000,1
边权
max int呢?
如果已经知道了父节点p到所有其他节点的距离之和F(p),能不能快速计算子节点c的F(c)呢?所有经过p才能到达c的点,距离会+val[p][c],而所有以c为根的子树中的节点,距离会-val[p][c]。所以我们进行如下计算:
(1)我们给树规定一个根。假设所有节点编号是1--n,我们可以简单地把1当作根,这样父子关系就确定了。
(2)定义数组siz[x]表示以节点x为根的子树有多少个节点&