【HDU2196】Computer | Tree dp, root dp

Main idea:

Abstract:

Find the farthest distance from each point

Question idea:

Typical template ideas

dp_u represents the length of the longest chain up from point i

dp_d represents the length of the longest chain down from point i

Just merge

This blog is only for the convenience of future queries, and does not explain the replacement of root dp carefully

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
****/

 

Guess you like

Origin blog.csdn.net/qq_43857314/article/details/111316134