做法:
a、大致想法是進行兩遍dfs,找到每個節點的向下的最長路徑 di 和向上的最長路徑 ui ,然後列舉每乙個點,再找到min(max( di , ui ))
b、補充細節:
1)根據樹的直徑求法,向下求的時候會有乙個最大值和次大值,例如節點 i 的 d1i , d2i,當更新 i 的某個子節點 j 的 uj 時候,一般情況是 w(i,j) + d1i ,但是如果能過達到 d1i 的路徑經過 j 點,那麼就要w(i,j) + d2i ,所以需要乙個節點記錄 d1 由誰更新而來。
2)因為邊權有負數,所以初值是-inf,但是要注意葉節點的特殊性,對於葉節點 i ,d1i , d2i均為0,並且在列舉的時候只比較 ui 。
**:
#include
#include
#include
#include
using
namespace std;
const
int n=
10010
,inf=
0x3f3f3f3f
;int e[n*2]
,idx,ne[n*2]
,h[n]
;int d1[n]
,d2[n]
,up[n]
,p[n]
;int n,w[n*2]
;bool leaf[n]
;void
add(
int a,
int b,
int c)
intdfs_d
(int u,
int father)
else
if(d>d2[u])}
if(d1[u]
==-inf)
return d1[u];}
void
dfs_u
(int u,
int father)
else
dfs_u
(j,u);}
}int
main()
dfs_d(1
,-1)
;dfs_u(1
,-1)
;int res=d1[1]
;for
(int i=
2;i<=n;i++
) cout
}
動態規劃 樹的中心 樹形DP
樹的中心 給定一棵樹,樹中包含 n n 個結點 編號1 n 1 n 和 n 1 n 1 條無向邊,每條邊都有乙個權值。請你在樹中找到乙個點,使得該點到樹中其他結點的最遠距離最近。第一行包含整數 n nn。接下來 n 1 n 1n 1 行,每行包含三個整數 ai,bi,c i ai,bi,ci,表示點...
AcWing1073 樹的中心(樹形dp)
lt s blog 題意 找乙個點,使得他到其他點的最長距離最小,邊權有正有負。最開始的時候我想這個點一定在樹的直徑上的中點位置處,wa了好多次後注意到題目資料範圍,把這個思路直徑否決了。如果我們將這顆樹化為乙個有根樹,那麼乙個點到其他點的最遠距離就是 max 他到子樹某個點的最遠距離,他經過父親節...
acwing 1073 樹的中心 (樹形DP)
我們要列舉每個點到其它點的最遠距離,那麼就會有兩種情況,向上走或者是向下走 假設我們列舉u點,向下走 dfs down u 更新當前節點向下走,葉子節點不需要更新 d1 u 表示 u點向下的最長路徑,d2 u 表示 u 點向下的次長路徑 p1 u 表示 u 的向下最長路徑經過的子節點 那麼我們只要每...