51NOD1405樹的距離之和 樹形DP

2021-08-28 02:47:05 字數 1356 閱讀 7058

51nod1405樹的距離之和

題意就是給定一棵無根樹,假設它有n個節點,節點編號從1到n, 求任意兩點之間的距離(最短路徑)之和。

首先由於這裡樹上的距離都是1,所以祖先與子孫的距離就是深度之差,我們可以一次樹形dp求出每個子樹包含的點的個數,並統計每個節點的深度,這樣所有點距離根節點的最短距離就是所有點的深度之和,之後我們想如何向下dpdp

dp,假設父親的答案為dp[

y]

dp[y]

dp[y

],兒子的答案為dp[

x]

dp[x]

dp[x

],兒子的子樹內節點個數為num

[x

]num[x]

num[x]

,若所有節點到y的最短距離之和為dp[y],則有dp[

x]=d

p[y]

−−nu

m[x]

+(n−

num[

x]),

beca

use:

x子樹內

的點距離

和−1,

x子樹外

的點距離

和+

1dp[x]=dp[y]--num[x]+(n-num[x]),because:x子樹內的點距離和-1,x子樹外的點距離和+1

dp[x]=

dp[y

]−−n

um[x

]+(n

−num

[x])

,bec

ause

:x子樹

內的點距

離和−1

,x子樹

外的點距

離和+1

**

#include#include#includeusing namespace std;

typedef long long ll;

const int maxn = 1e5+5;

int dept[maxn];

ll dp[maxn];

int num[maxn];

int n;

vectorv[maxn];

void dfs(int x,int rt,int dep)

return ;

}void dfs2(int x,int rt)

return ;

}int main()

dfs(1,-1,0);

for(int i=1;i<=n;i++) dp[1]+=dept[i];

dfs2(1,-1);

for(int i=1;i<=n;i++) cout

}

51nod 1405 樹的距離之和

給定一棵無根樹,假設它有n個節點,節點編號從1到n,求任意兩點之間的距離 最短路徑 之和。input 第一行包含乙個正整數n n 100000 表示節點個數。後面 n 1 行,每行兩個整數表示樹的邊。output 每行乙個整數,第i i 1,2,n 行表示所有節點到第i個點的距離之和。input示例...

51Nod 1405 樹的距離之和

acm模版 根據題意,這是一顆樹,所以每兩點之間的路徑一定是唯一的。這裡讓求所有點到第i個結點的距離和,其實也就是其他所有結點到第i個結點的距離和。通過觀察發現,只要我們找到了乙個點對應的結果,那麼其他所有的點都可以通過這個結果擴充套件出來,利用邊的關係。比如說,我們知道了第乙個結點對應的結果,並且...

51nod 1405 樹的距離之和

給定一棵無根樹,假設它有n個節點,節點編號從1到n,求任意兩點之間的距離 最短路徑 之和。input 第一行包含乙個正整數n n 100000 表示節點個數。後面 n 1 行,每行兩個整數表示樹的邊。output 每行乙個整數,第i i 1,2,n 行表示所有節點到第i個點的距離之和。input示例...