题目大意:
抽象一下:
求出距离每个点的最远距离
题目思路:
典型的模板思路了
dp_u代表i点向上的最长链的长度
dp_d代表i点向下的最长链的长度
进行合并即可
此博客只是为了以后查询方便,不仔细讲解换根dp
Code:
/*** keep hungry and calm CoolGuang! ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define d(x) printf("%lld\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17;
const ll maxn = 2e5+700;
const int mod= 1e9+7;
const int up = 1e9;
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
vector<pair<int,int>>v[maxn];
ll dp_d[maxn][2],res[maxn],dp_u[maxn];
void dfs(int u,int fa){
for(auto x:v[u]){
int e = x.first,w = x.second;
if(e == fa) continue;
dfs(e,u);
if(dp_d[u][1] < dp_d[e][1]+w){
dp_d[u][0] = dp_d[u][1];
dp_d[u][1] = dp_d[e][1] + w;
}else if(dp_d[u][0] < dp_d[e][1] + w)
dp_d[u][0] = dp_d[e][1] + w;
}
}
void dfs(int u,int fa,int w){
ll res = 0;
if(u!=fa){
dp_u[u] = max(dp_u[u],w+dp_u[fa]);
if(dp_d[fa][1] == dp_d[u][1]+w) dp_u[u] = max(dp_u[u],w+dp_d[fa][0]);
else dp_u[u] = max(dp_u[u],w+dp_d[fa][1]);
}
for(auto x:v[u]){
int e = x.first;
if(e == fa) continue;
dfs(e,u,x.second);
}
}
int main(){
while(~scanf("%lld",&n)){
for(int i=1;i<=n;i++) v[i].clear();
for(int i=2;i<=n;i++){
int x,y;read(x);read(y);
v[x].push_back({i,y});
v[i].push_back({x,y});
}
for(int i=1;i<=n;i++) dp_d[i][0] = dp_d[i][1] = dp_u[i] = 0;
dfs(1,1);
dfs(1,1,1);
for(int i=1;i<=n;i++)
printf("%lld\n",max(dp_d[i][1],dp_u[i]));
}
return 0;
}
/***
4 3
0 0
1 0
2 0
3 1
****/