题目:http://acm.hdu.edu.cn/showproblem.php?pid=2196
题意:给出一棵树,让求每个点能到达的最远距离
思路:
dp[u][0]表示u的子树中所能达到的最远距离
dp[u][1]表示u的子树中所能达到的次远距离
dp[u][2]表示u的父亲结点所能达到的最远距离
难点是在求dp[u][2]上
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
struct edge
{
int v,w;
};
vector<edge> G[N];
int maxn,dp[N][3],p[N];
void dfs1(int u,int fa)
{
dp[u][0] = 0;
dp[u][1] = 0;
for(auto e : G[u])
{
int v = e.v,w = e.w;
if(v == fa)
continue;
dfs1(v,u);
if(dp[v][0]+w >= dp[u][0])
{
dp[u][1] = dp[u][0];//次长路
dp[u][0] = dp[v][0]+w;//最长路
}
else if(dp[v][0]+w > dp[u][1])
dp[u][1] = dp[v][0]+w;//次长路
}
}
void dfs2(int u,int fa)
{
for(auto e : G[u])
{
int v = e.v,w = e.w;
if(v == fa)
continue;
if(dp[u][0] == dp[v][0] + w)//最大距离经过v
dp[v][2] = max(dp[u][2],dp[u][1]) + w;
else
dp[v][2] = max(dp[u][2],dp[u][0]) + w;
dfs2(v,u);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 1;i <= n;i++)
G[i].clear();
int u,v,w;
for(int i = 2;i <= n;i++)
{
v = i;
scanf("%d%d",&u,&w);
G[u].push_back({v,w});
G[v].push_back({u,w});
}
dfs1(1,-1);
dfs2(1,-1);
for(int i = 1;i <= n;i++)
printf("%d\n",max(dp[i][0],dp[i][2]));
}
return 0;
}