51nod 4級演算法 1405

2021-08-04 06:29:24 字數 1611 閱讀 3801

給定一棵無根樹,假設它有n個節點,節點編號從1到n, 求任意兩點之間的距離(最短路徑)之和。
第一行包含乙個正整數n (n <= 100000),表示節點個數。

後面(n - 1)行,每行兩個整數表示樹的邊。

output
每行乙個整數,第i(i = 1,2,...n)行表示所有節點到第i個點的距離之和。
4

1 23 2

4 2

535

5

思路:樹形dp?

dp[u]表示以結點u到其子樹所有結點的距離和;

cnt[u]表示包括u在內的子樹中所有結點個數;

v為u的子結點,則有: cn

t[u]

=(∑c

nt[v

])+1

這個好理解,子節點之和加上自己 dp

[u]=

∑(dp

[v]+

cnt[

v])

這樣理解:dp

[u]=

∑dp[

v]+∑

cnt[

v],所有子節點的子節點距離和+每個子節點需要多走一步。

所以可以從葉子結點往上進行狀態轉移,直至算出根節點的dp值又注意到若dp[u]表示u到其他所有結點的距離和,v為u的子結點,則有: dp

[v]=

dp[u

]−cn

t[v]

+(n−

cnt[

v])

dp[v

]=dp

[u]+

n−2∗

cnt[

v]v子樹中的所有結點的到v的距離比其到u的距離的各少1,共cnt[v]個結點,則需要減去cnt[v]

不在v子樹中的所有結點到v的距離比其到u的距離各多1,共n−cnt[v]個結點,則需要加上n−cnt[v]

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn= 1e5+100;

vector

node[maxn];

long

long dp[maxn];

long

long cnt[maxn];

int n;

void dp_up(int u,int p)

}}void dp_down(int u,int p)

}}int main ()

dp_up(1,0);

dp_down(1,0);

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

}

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個節點的無根樹,求每個節點分別到其他n 1個節點的距離之和。思路 設dp x 表示節點x到其他n 1個節點的距離和。乙個dp x 是很好求的,把x當成根,一遍dfs,把所有點的深度加起來,就可以求出dp x 得知dp x 如何求得dp y 呢?此時x是父節點,y是兒子節點。我們再增加乙個兒...