HDU-2196 Computer
题意:
就问你每个节点到以这个点为根的子树的叶子节点的最远距离。
链接: http://acm.hdu.edu.cn/search.php?action=listproblem
思路:
我们设DP[i][0]表示以i节点为根节点的子树中的最远距离,
DP[i][1]表示以i节点为根节点的子树中的次远距离,
DP[i][2]表示通过i的父亲节点能走到的最远距离。
答案即为max(DP[i][2],DP[i][0]),通过两遍dfs解决
代码:
#include <bits/stdc++.h> using namespace std; const int MAXN = 2e5+ 5; const int INF = 1e16; typedef long long ll; int a[MAXN],dp[MAXN][3]; int head[MAXN],tot; struct node { int to,nxt,val; } e[MAXN<<2]; void add(int x,int y,int z) { e[tot].to=y; e[tot].val=z; e[tot].nxt=head[x]; head[x]=tot++; } void dfs1(int u,int fa) //由下至上更新 { for(int i=head[u]; ~i; i=e[i].nxt) { int v=e[i].to; dfs1(v,u); int temp=dp[v][0]+e[i].val; if(temp>=dp[u][0]) { dp[u][1]=dp[u][0]; dp[u][0]=temp; } else dp[u][1]=max(dp[u][1],temp); } } void dfs2(int u,int fa) //由上至下更新 { for(int i=head[u]; ~i; i=e[i].nxt) { int v=e[i].to; if(dp[v][0]+e[i].val==dp[u][0]) dp[v][2]=max(dp[u][2],dp[u][1])+e[i].val; else dp[v][2]=max(dp[u][0],dp[u][2])+e[i].val; dfs2(v,u); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; while(cin>>n) { memset(head,-1,sizeof(head));tot=0; memset(dp,0,sizeof(dp)); for(int i=2; i<=n; i++) { int x,z; cin>>x>>z; add(x,i,z); } dfs1(1,-1); dfs2(1,-1); for(int i=1; i<=n; i++) cout<<max(dp[i][0],dp[i][2])<<endl; //cout<<max(dp[n][0],dp[n][2])<<endl; } }