acwing 1073 樹的中心 (樹形DP)

2021-10-21 22:42:59 字數 1608 閱讀 1292

我們要列舉每個點到其它點的最遠距離,那麼就會有兩種情況,向上走或者是向下走

假設我們列舉u點,向下走 dfs_down(u) 更新當前節點向下走,葉子節點不需要更新

d1[u] 表示 u點向下的最長路徑,d2[u] 表示 u 點向下的次長路徑 ,p1[u] 表示 u 的向下最長路徑經過的子節點 。 那麼我們只要每次列舉u節點的兒子,然後更新即可

向上走:dfs_up 傳入 u 節點, 我們更新它的每乙個兒子(因為開始傳入的u是根節點不需要向上更新)

對於u的兒子 j ,第一步肯定是向上走,距離是 w[i] , 那麼接接下來就有兩種方式,繼續向上或向下 ,如果是從u節點向下的話,j是最長路徑上的乙個點,我們就選擇次長的路徑,如果j不是最長路徑上的點,我們就選擇最長路 ,然後向上,向下取乙個最大即可

#include

#include

#include

#include

#include

using

namespace std;

const

int n =

1e4+10;

const

int inf =

0x3f3f3f3f

;int n;

int h[n]

, e[n *2]

, w[n *2]

, ne[n *2]

, idx;

int d1[n]

, d2[n]

, p1[n]

, up[n]

;//p1陣列標記這個節點的最長路徑要經過哪個子節點

int is[n]

;//標記是否為葉子節點

void

add(

int a,

int b,

int c)

//向下求最長

intdfs_down

(int u,

int father)

if(d1[u]

==-inf)

return d1[u];}

//向上求最長

intdfs_up

(int u,

int father)

}int

main()

dfs_down(1

,-1)

;dfs_up(1

,-1)

;int res = d1[1]

;for

(int i =

2; i <= n; i++

) cout << res << endl;

return0;

}

AcWing 1073 樹的中心

原題鏈結 考察 樹形dp 1072.樹的最長路徑 該題的延伸 思路 上題求的是父節點往下的最大值 次大值.這道題求的是點與點的最大距離.這個可以是該點往下的最長距離,也可以是該點往上的最長距離.假設某點為根,往下的最長距離上一題已經求出.往上的最大距離是 到父節點的距離 max 父節點往下的最大距離...

AcWing 1073 樹的中心

題目傳送門 這個問題是樹形dp中的一類經典模型,常被稱作換根dp 同樣,先來想一下如何暴力求解該問題 先列舉目標節點,然後求解該節點到其他節點的最遠距離 時間複雜度為 o n 2 對於本題的資料規模,十分極限,經測試只能過7 11,見最下面 考慮如何優化求解該問題的方法 思考一下 在確定樹的拓撲結構...

AcWing1073 樹的中心(樹形dp)

lt s blog 題意 找乙個點,使得他到其他點的最長距離最小,邊權有正有負。最開始的時候我想這個點一定在樹的直徑上的中點位置處,wa了好多次後注意到題目資料範圍,把這個思路直徑否決了。如果我們將這顆樹化為乙個有根樹,那麼乙個點到其他點的最遠距離就是 max 他到子樹某個點的最遠距離,他經過父親節...