鏈結 : 傳送門
題意: 給你乙個n個節點的棵樹,然後給你和 第i臺電腦與第a臺電腦相連的花費 v 問你最長的線路是多長(求樹上任意節點所能達到的最遠點的距離)
樹形dp ,開個陣列 分別記錄這個點到子樹最遠節點的最長距離
和次長距離
和記錄到父節點上的最長距離
這樣在樹上dp
1. 求子樹最長
和次長
dp[u][0] =max(dp[u][0],dfs(v,u)+val) 子樹最長距離 =max(子樹節點到子樹的子樹的最遠距離 + 子樹到根的距離 , 子樹最長距離);
a.最長更新
dp[u][1] =max(dp[u][1],dp[u][0])
b.最長不更新
dp[u][1]=max(dp[u][1],dfs(v,u)+val)
2.求父節點
最長
a. 如果父節點最長子樹通過
該節點,則父節點最長等於父節點次長加到子節點的距離
或者父節點在其父節點的最長加到子節點的距離
dp[v][2]=max(dp[u][2]+val,dp[u][1]+val)
b. 如果不通過那就是父節點最長等於父節點最長加到子節點的距離
或者父節點在其父節點的最長加到子節點的距離
dp[v][2]=max(dp[u][2]+val,dp[u][0]+val)
#include
using
namespace
std;
#define ll long long
#define rd(a) scanf("%d",&a)
#define rlld(a) scanf("%lld",&a)
#define me(a,b) memset(a,b,sizeof(a))
const
int inf= 0x3f3f3f3f;
const
int maxn=1e4 + 3;
const ll mod =1e9+7;
int dist[maxn][3];
struct nodess[maxn*2];
int head[maxn];
int pre[maxn];
int cnt=0;
inline
void add(int u,int v,int val)
inline
void init ()
int dfs(int u,int fa)
else
}return dist[u][0];
}void dfs1(int u,int fa)
}int main()
dfs(1,-1);
dfs1(1,-1);
for(int i=1;i<=n;i++) cout
<< max(dist[i][0],dist[i][2])0;}
題解 hdu2196 樹形DP
題目鏈結 分析 求乙個樹中所有節點能到達的最遠距離f i 要用兩個dfs。首先第乙個dfs求出所有每個節點i在其子樹中的正向最大距離和正向次大距離和dist i 0 和dist i 1 如果i節點在子樹中最大距離經過了2號兒子,那麼次大距離就是不經過2號兒子的最大距離 並且還要標記longest i...
HDU 2196 經典樹形DP
大體思路是將乙個無根數轉化為有根樹,再深搜兩次,第一次將每個子樹的根距其葉子的最遠距離求出來 自下而上 第二次求每個節點到其他結點的最遠距離 自上而下 但因為在第二次深蒐時可能會碰到乙個結點的父節點的最遠距離經過它,所以我們需要儲存乙個最長距離和乙個次長距離 include include incl...
HDU 2196 樹形DP經典題
經典的樹形dp題。題意是求樹中每個點到所有葉子節點的距離的最大值是多少。由於對於乙個節點來說,可能得到的距離最大的值的路徑來自他的子樹,或者從他的父節點過來,所以用兩次dfs。第一次dfs求出所有節點在他的子樹範圍內到葉子節點距離的最大值和第二大的值,第二次dfs更新從父節點過來的情況就可以了。因為...