樹的中心
給定一棵樹,樹中包含 n
'>n 個結點(編號1 n
'>1-n)和 n−1
'>n−1 條無向邊,每條邊都有乙個權值。
請你在樹中找到乙個點,使得該點到樹中其他結點的最遠距離最近。
第一行包含整數 n
'>nn。
接下來 n−1
'>n−1n−1 行,每行包含三個整數 ai,
bi,c
i'>ai,bi,ci,表示點 a
i'>ai和 b
i'>bi之間存在一條權值為 c
i'>ci 的邊。
輸出乙個整數,表示所求點到樹中其他結點的最遠距離。
資料範圍:1≤
n≤10000
,'>1≤n≤10000,1≤n≤10000,1≤
ai,b
i≤n,
'>1≤ai,bi≤n1≤
ci≤10
5'>1≤ci≤1e5
思路:
對於某乙個結點,找到他向下查詢距離最大值d1和距離第二大值d2 ,這個**可以借鑑 我的 樹的最長 路徑**動態規劃:樹的最長路徑 樹形dp - 朱朱成 - (cnblogs.com)的模板,
但還需要找到向上查詢的最大路徑,因為這個結點也是某乙個結點的子節點,所以他向上查詢只會有一顆子樹,求出這條路徑就行。這就是這題的關鍵**dfs_up實際上是自上而下完善。1≤
n≤10000
,'>1≤a
i,bi
≤n,'>1≤c
i≤105
'>向下dfs完善向下的路徑實際上是自下而上完善的過程,因為只有dfs到了最底層,也就是葉子,才算得出來倒數第二個,才算得出來倒數第三個...才能算出第乙個結點。dfs_up就是自上而下完善的,1≤
n≤10000
,'>1≤a
i,bi
≤n,'>1≤c
i≤105
'>對於每乙個結點,他向上查詢的最大值 ,我們把這個結點稱為j結點,他的根結點,也就是上乙個結點,我們稱為u結點,那麼對於j向上查詢的最大路徑,存在兩種情況①:若j在u的向下查詢的最大路徑上,1≤n
≤10000
,'>1≤a
i,bi
≤n,'>1≤c
i≤105
'>
他向上查詢的最大路徑就是u和j的權值加上max(u向上查詢的最大路徑up和u向下查詢的第二大路徑d2)因為是自上而下完善 所以對於j的根u的向上查詢的最大值up一定是已經算出來的,
②:如果j不在u向下查詢的最大路徑上,那麼j向上查詢的最大路徑up就等於max(u的d1,u的up)+上j u 邊的權值。
關鍵**:
完整ac**:
1 #include2 #include3using
namespace
std;
4const
int maxn = 1e4 + 5;5
const
int inf=0x7fffffff;6
int head[maxn], to[2 * maxn], nex[2 * maxn], val[2 * maxn], index;//
鄰接表7
intn, a, b, c, ans;
8int
d1[maxn],d2[maxn],up[maxn],road[maxn];9//
d1:向下走的最大長度 d2:向下走的次大長度 ups:向上走的最大長度 road記錄向下最大長度的第乙個結點
10void add(int a, int b, int
c)11
18int dfs_d(int u,int
father)
1930
return
d1[u];
3132}33
void dfs_u(int u,int
father)
3445}46
intmain()
4756 dfs_d(1,-1);//
father先初始化為-1
57 dfs_u(1,-1
);58
int res=inf;
59for(int i=1;i<=n;++i)
6063 cout <
64return0;
65 }
DP 樹形 DP 樹的中心
做法 a 大致想法是進行兩遍dfs,找到每個節點的向下的最長路徑 di 和向上的最長路徑 ui 然後列舉每乙個點,再找到min max di ui b 補充細節 1 根據樹的直徑求法,向下求的時候會有乙個最大值和次大值,例如節點 i 的 d1i d2i,當更新 i 的某個子節點 j 的 uj 時候,...
動態規劃 樹形DP
樹形dp,即在樹上進行的動態規劃,由於樹固有的遞迴性質,因此樹形dp往往也遞迴進行。某大學有 n nn 個職員,編號為 1.n1.n 1.n 他們之間有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。現在有個周年慶宴會,宴會每邀請來乙個職員都會增加一定的快樂指數 r ...
( 動態規劃專題 ) 樹形dp
動態規劃專題 樹形dp 直接看例題 p2015 二叉蘋果樹 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3...