其他分享
首页 > 其他分享> > AcWing 1073. 树的中心

AcWing 1073. 树的中心

作者:互联网

每个节点到其余节点的最长距离可以分为向上走和向下走两类:
向下走:dfs_down,求每个子节点向下走的最长距离,用子节点维护父节点
向上走:dfs_up,分为两类,一类是父节点向下走的的最长距离,一类是向上走的,因为父节点向下走的最长距离可能经过此节点,所以对于每个节点需要维护向下走的最大值和次大值
#include<bits/stdc++.h>
using namespace std;

const int N = 1e4+10,INF = 0x3f3f3f3f;

int n;    
int head[N],cnt;

int p1[N],d1[N],d2[N],u[N];

struct BIAN{
    int to,next,len;
}bian[2*N];

void add(int x,int y,int z){
    bian[++cnt].to=y;
    bian[cnt].len=z;
    bian[cnt].next=head[x];
    head[x]=cnt;
}

int dfs_down(int cur,int fa){
    d1[cur]=d2[cur]=0;
    for(int i=head[cur];i!=-1;i=bian[i].next){
        int y=bian[i].to;
        if(y==fa) continue;
        int d=dfs_down(y,cur)+bian[i].len;
        if(d>d1[cur]){
            p1[cur]=y;
            d2[cur]=d1[cur];
            d1[cur]=d;
        }
        else if(d>d2[cur]) d2[cur]=d;
    }
    // if(d1[cur]==-INF) return 0;
    return d1[cur];
}

void dfs_up(int cur,int fa){
    for(int i=head[cur];i!=-1;i=bian[i].next){
        int y=bian[i].to;
        if(y==fa) continue;
        if(p1[cur]==y) u[y]=max(u[cur],d2[cur])+bian[i].len;
        else u[y]=max(u[cur],d1[cur])+bian[i].len;
        dfs_up(y,cur);
    }
}

int main(){
    memset(head,-1,sizeof head);
    cin>>n;
    for(int i=1;i<n;i++){
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }
    dfs_down(1,0);
    dfs_up(1,0);
    int ans=INF;
    for(int i=1;i<=n;i++) ans=min(ans,max(d1[i],u[i]));
    cout<<ans;
    return 0;
}

标签:head,cur,中心,int,1073,bian,dfs,d1,AcWing
来源: https://www.cnblogs.com/xhy666/p/16296758.html