樹的直徑(樹形dp)
阿新 • • 發佈:2019-02-14
設定狀態dp[u][2]
dp[u][0]表示距離u的最長距離,dp[u][1]表示距離u的次長距離(與最長距離的節點不在同一顆子樹上)然後狀態方程為
ans=(ans,dp[u][0]+dp[u][1])ans為樹的直徑答案
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #include <cmath> using namespace std; const int maxn=100100; struct EDGE { int v, w, next; }e[maxn]; int cnt; int head[maxn]={}; void Add(int u, int v, int w){ e[cnt].v = v; e[cnt].w = w; e[cnt].next = head[u]; head[u] = cnt ++; } int dp[2][maxn]={}; int n,s,ans; void dfs(int u,int fa){ for(int i=head[u];i!=-1;i=e[i].next)if(e[i].v!=fa){ int v=e[i].v,w=e[i].w; dfs(v,u); if(dp[0][v]+w>dp[0][u]){ dp[1][u]=dp[0][u]; dp[0][u]=dp[0][v]+w; } else if(dp[0][v]+w>dp[1][u]) dp[1][u]=dp[0][v]+w; } ans=max(ans,dp[0][u]+dp[1][u]); return; } int main() { scanf("%d%d",&n,&s); memset(dp,0,sizeof(dp));ans=0;cnt=0; memset(head,-1,sizeof(head)); int sum=0; for(int i=0;i<n-1;i++){ int u, v, w; scanf("%d %d %d",&u,&v,&w); Add(u,v,w); Add(v,u,w); } dfs(s,-1); printf("%d\n",ans); return 0; }