AcWing 1073 樹的中心

2022-09-11 10:03:11 字數 2810 閱讀 2768

題目傳送門

這個問題是樹形dp中的一類經典模型,常被稱作換根dp

同樣,先來想一下如何暴力求解該問題:先列舉目標節點,然後求解該節點到其他節點的最遠距離

時間複雜度為 \(o(n^2)\),對於本題的資料規模,十分極限,經測試只能過7/11,**見最下面

考慮如何優化求解該問題的方法

思考一下:在確定樹的拓撲結構後單獨求乙個節點的最遠距離時,會在該樹上去比較哪些路徑呢?

此處就要引入換根dp的思想了

換根dp一般分為三個步驟:

指定任意乙個根節點

一次dfs遍歷,統計出當前子樹內的節點對當前節點的貢獻

一次dfs遍歷,統計出當前節點的父節點對當前節點的貢獻,然後合併統計答案

那麼我們就要先dfs一遍,預處理出當前子樹對於根的最大貢獻(距離)次大貢獻(距離)

處理次大貢獻(距離)的原因是:

如果當前節點是其父節點子樹最大路徑上的點,則父節點子樹最大貢獻不能算作對該節點的貢獻

因為我們的路徑是簡單路徑,不能走回頭路

然後我們再dfs一遍,求解出每個節點的父節點對他的貢獻(即每個節點往上能到的最遠路徑),兩者比較,取乙個max即可

d1[u]:存下u節點向下走的最長路徑的長度

d2[u]:存下u節點向下走的第二長的路徑的長度

p1[u]:存下u節點向下走的最長路徑是從哪乙個節點下去的

p2[u]:存下u節點向下走的第二長的路徑是從哪乙個節點走下去的

up[u]:存下u節點向上走的最長路徑的長度

#includeusing namespace std;

const int n = 10010;

const int m = n << 1;

const int inf = 0x3f3f3f3f;

int n;

int h[n], e[m], w[m], ne[m], idx;

int d1[n]; //下行最長距離

int d2[n]; //下行次長距離

int up[n]; //上行最長距離

int p1[n]; //下行最長距離是走的哪乙個節點獲得的

//鄰接表模板

void add(int a, int b, int c)

//統計出當前子樹內的節點對當前節點的貢獻

void dfs_d(int u, int father) else if (d1[j] + w[i] > d2[u]) //如果可以更新次長

d2[u] = d1[j] + w[i]; //那就更新

}}//統計出當前節點的父節點對當前節點的貢獻,然後合併統計答案

void dfs_u(int u, int father)

}int main()

//換根dp,兩次dfs

dfs_d(1, -1);

dfs_u(1, -1);

//遍歷每乙個節點,找出它的最大上行距離和最大下行距離,然後取最小值

int res = inf;

for (int i = 1; i <= n; i++) res = min(res, max(d1[i], up[i]));

//輸出

printf("%d\n", res);

return 0;

}

#include using namespace std;

//直接暴力換根

//暴力辦法,可以通過 7/11個資料

const int n = 10010;

const int m = n * 2;

const int inf = 0x3f3f3f3f;

int n;

int h[n], e[m], w[m], ne[m], idx;

int d[n];

//鄰接表模板

void add(int a, int b, int c)

int dfs(int u, int father)

return d[u];

}int main()

int res = inf;

//從每乙個點出發,分別求乙個此點到其它各點的最長距離,然後求乙個min

for (int i = 1; i <= n; i++) res = min(res, dfs(i, -1));

//輸出

printf("%d\n", res);

return 0;

}

AcWing 1073 樹的中心

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

AcWing1073 樹的中心(樹形dp)

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

acwing 1073 樹的中心 (樹形DP)

我們要列舉每個點到其它點的最遠距離,那麼就會有兩種情況,向上走或者是向下走 假設我們列舉u點,向下走 dfs down u 更新當前節點向下走,葉子節點不需要更新 d1 u 表示 u點向下的最長路徑,d2 u 表示 u 點向下的次長路徑 p1 u 表示 u 的向下最長路徑經過的子節點 那麼我們只要每...