hdoj2196(樹形dp,樹的直徑)

2022-08-21 18:33:15 字數 1143 閱讀 8281

題意:給出一棵樹,求每個結點可以到達的最遠距離。

思路:如果求得是樹上最長距離,兩次bfs就行。但這裡求的是所有點的最遠距離,樹形dp的經典題,想了乙個小時,還是dp做得太少。分析可得對任意結點u,它的最長距離要麼是向下延伸的最長距離,要不向上延伸的最長距離。

我們用dp[u][0]表示節點u向下(子結點)的最長距離,pt[u]記錄該最長距離經過的第乙個子結點編號,比如最長距離經過u->v,那麼pt[u]=v。dp[u][1]記錄u向下的次短距離,dp[u][0]、dp[u][1]通過一次dfs可以得到,該dfs是由子結點得到父結點的資訊。

dp[u][2]記錄節點u向上(父結點)的最長距離,假設u的父結點為k,分兩種情況考慮:

1.pt[k]=u(k向下的最長路經過u):dp[u][2]=wku+max(dp[k][1],dp[k][2]),即父結點走次長距離,還是向上距離。

2.pt[k]!=u:dp[u][2]=wku+max(dp[k][0],dp[k][2]),即父結點走最長距離,還是向上距離。

對每個結點,結果為max(dp[u][0],dp[u][2])。

ac**:

#include#include

#include

using

namespace

std;

const

int maxn=10005

;struct

nodeedge[maxn];

int n,dp[maxn][3

],pt[maxn],head[maxn],cnt;

void adde(int u,int v,int

w)void dfs1(int

u)

else

if(dp[v][0]+w>dp[u][1

]) dp[u][

1]=dp[v][0]+w;

}}void dfs2(intu)}

intmain()

dfs1(1);

dfs2(1);

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

printf(

"%d\n

",max(dp[i][0],dp[i][2

]));

}return0;

}

hdoj3534 樹形dp,求樹的直徑的條數

題意 給出一棵樹,求樹上最長距離 直徑 以及這樣的距離的條數。思路 如果只求直徑,用兩次dfs即可。但是現在要求最長距離的條數,用dp1 u 記錄以u為根的子樹中葉子結點到u的最長距離,dp2 u 表示最長距離的條數,這兩個比較容易維護。dfs過程中更新答案,用ans1表示樹上直徑,ans2表示該直...

DP 樹形 DP 樹的中心

做法 a 大致想法是進行兩遍dfs,找到每個節點的向下的最長路徑 di 和向上的最長路徑 ui 然後列舉每乙個點,再找到min max di ui b 補充細節 1 根據樹的直徑求法,向下求的時候會有乙個最大值和次大值,例如節點 i 的 d1i d2i,當更新 i 的某個子節點 j 的 uj 時候,...

樹形dp 樹的重心

1.只需要求出最大子樹中節點數最小的數目即可 題意 有乙個國王要把他的領土分給兩個兒子,國王的領土是一棵樹,n個結點,n 1條邊把這些結點連起來,現在大小兒子要選擇乙個點作為他的首都,那麼除首都分別是這兩個兒子之外,其他的城市 結點 根據離誰近就歸誰所有,如果一樣遠的話就歸大兒子所有,現在假設兩個人...