[樹形DP]HDU 2196-Computer
阿新 • • 發佈:2018-10-02
() 表示 裏的 其他 tchar long struct 更新 如果
題目大意
求樹中每個點到任意點的最長距離
思路
該距離有兩種,一種是經過父親節點的,一種是子樹裏的
定義dp[x][0/1]表示x到葉子節點的最大距離和次大距離
dp[x][2]表示經過父親節點的最長路徑
dp[x][2]可以是先走到父親節點,再走到父親的其他兒子,也可能是走到父親節點再走到父親的父親
此時若父親的最遠葉子節點經過該點,就用次大值更新,否則用最大值更新
#include<cstdio> #include<cstring> #include<iostream> #define max(a,b) ((a)>(b)?(a):(b)) typedef long long ll; const int maxn=10000+5; inline int Read(){ int x=0;char c=getchar(); while(‘0‘>c||c>‘9‘)c=getchar(); while(‘0‘<=c&&c<=‘9‘)x=(x<<1)+(x<<3)+c-48,c=getchar(); return x; } struct Edge{ int to,nxt,data; }e[maxn<<1]; int n,head[maxn],cnt,dp[maxn][3]; inline void Insert(int x,int y,int z){ e[++cnt].to=y;e[cnt].data=z; e[cnt].nxt=head[x];head[x]=cnt; } #define y e[i].to void Dfs1(int x){ dp[x][0]=dp[x][1]=dp[x][2]=0; for(int i=head[x];i;i=e[i].nxt){ Dfs1(y); if(dp[y][0]+e[i].data>dp[x][0]){ dp[x][1]=dp[x][0]; dp[x][0]=dp[y][0]+e[i].data;//dp[x][0]表示x到子樹內葉節點的最長距離 } else dp[x][1]=max(dp[x][1],dp[y][0]+e[i].data);//dp[x][1]表示次長距離 } } void Dfs2(int x){ for(int i=head[x];i;i=e[i].nxt){ if(dp[x][0]==dp[y][0]+e[i].data) dp[y][2]=max(dp[x][1],dp[x][2])+e[i].data; else dp[y][2]=max(dp[x][0],dp[x][2])+e[i].data; Dfs2(y); }//dp[x][2]表示經過父節點取得的最長路徑,此時可以到父親節點再到父親的其他兒子,也可以從父親到父親的父親 //如果父節點到葉子節點的最大值經過y,那麽就用次大值更新,否則就用最大值 } #undef y int main(){ int x,y; while(scanf("%d",&n)!=EOF){ cnt=0; memset(head,0,sizeof(head)); for(int i=2;i<=n;++i)x=Read(),y=Read(),Insert(x,i,y); Dfs1(1);Dfs2(1); for(int i=1;i<=n;++i)printf("%d\n",max(dp[i][0],dp[i][2])); } return 0; }
[樹形DP]HDU 2196-Computer