AcWing 1073. 树的中心

思路

这是一道很好的树形dp题,即用到了用子节点更新父节点信息的普遍情况,又用到了用父节点更新子节点的情况,所以掌握这一道题是很有必要的,废话不多说,下面开始讲讲我对y总的思路的理解

首先分析题目,其实是要我们把每一个点到其他点的最长距离求出来,再求一个其中最短的就可以了,我们来分析一下每一个点可以再树上怎么走,其实就是向上和向下走

我们用 d1[u],d2[u],up[u],p1[u],p2[u]分别存一下需要的信息,这些数据存的是:
d1[u]:存下u节点向下走的最长路径的长度
d2[u]:存下u节点向下走的第二长的路径的长度
p1[u]:存下u节点向下走的最长路径是从哪一个节点下去的
p2[u]:存下u节点向下走的第二长的路径是从哪一个节点走下去的
up[u]:存下u节点向上走的最长路径的长度

向下走是很容易的,dfs就可以了,那怎么向上走呢?其实向上走就是求一个点的父节点的不走该节点的最长路径,其实我们知道了每一个节点向下走的长度就可以知道向上的最长路径了,一个子节点 j 的向上最长路径就是 它的父节点 u 的最长向上路径和最长向下路径取最大值,如果向下最长路径经过了 j 就改为第二长的向下路径,对应代码:

 if(p1[u]==j)up[j]=max(up[u],d2[u])+w[i];
 else up[j]=max(up[u],d1[u])+w[i];

图有点丑…
在这里插入图片描述在这里插入图片描述

代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5+5,INF=1e9;
int d1[N];int d2[N];int up[N];int p1[N];int p2[N];int h[N];int ne[2*N];int e[2*N];int idx;
int w[N];
int n;
void add(int a,int b,int c){
    e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}
int dfs_down(int u,int father){//返回u的最长向下路径
    d1[u]=d2[u]=-INF;
    for(int i=h[u];~i;i=ne[i]){
        int j=e[i];
        if(j==father)continue;
        int dist=dfs_down(j,u)+w[i];
        if(dist>d1[u]){//更新一下最长和第二长的路径,并记录下从该路径是从哪一个点下去的
            d2[u]=d1[u],d1[u]=dist;
            p2[u]=p1[u];p1[u]=j;
        }
        else if(dist > d2[u]){
            d2[u]=dist;
            p2[u]=j;
        }
    }
    if(d1[u]==-INF)d1[u]=d2[u]=0;//如果没有改变过该点的距离,就证明这个点是叶节点
    return d1[u];
}
void dfs_up(int u,int father){//用父节点更新一下子节点向上的最长路径
    for(int i=h[u];~i;i=ne[i]){
        int j=e[i];
        if(j==father)continue;
        if(p1[u]==j)up[j]=max(up[u],d2[u])+w[i];//如果从父节点向下的最长路径进过了要更新的子节点,那么就用第二长的路径更新
        else up[j]=max(up[u],d1[u])+w[i];
        dfs_up(j,u);
    }
}
int main(){
    cin >> n;
    memset(h,-1,sizeof h);
    for(int i=0;i<n-1;i++){
        int a,b,c;
        cin >> a >> b >> c;
        add(a,b,c);add(b,a,c);
    }
    dfs_down(1,-1);
    dfs_up(1,-1);
    int res=INF;
    for (int i = 1; i <= n; i ++ ) res = min(res, max(d1[i], up[i]));
    cout << res;
}

发布了175 篇原创文章 · 获赞 1 · 访问量 4259

猜你喜欢

转载自blog.csdn.net/weixin_45080867/article/details/103435754