旅游规划

题意:给一棵树,输出树上所有最长路径包含的节点

 

树的直径的应用

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 200005
#define N2 400005
using namespace std;

inline int read()
{
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

int n,cnt,ans=-1;
int v[N2],head[N],nxt[N2];
int d1[N],d2[N],c[N],w[N];

void add(int x,int y)
{
    v[++cnt]=y;
    nxt[cnt]=head[x];
    head[x]=cnt;
}

int dfs(int x,int fa)
{
    for(int i=head[x];i!=-1;i=nxt[i])
    {
        int t=v[i];
        if(t==fa) continue;
        int s=dfs(t,x)+1;
        if(s>d1[x])
        {
            d2[x]=d1[x];
            d1[x]=s;
            c[x]=t;
        }
        else if(s>d2[x])
            d2[x]=s;
    }
    ans=max(ans,d1[x]+d2[x]);
    return d1[x];
}

void dfs2(int x,int fa)
{
    if(x)
    {
        if(c[fa]!=x)
            w[x]=max(w[fa],d1[fa])+1;
        else
            w[x]=max(w[fa],d2[fa])+1;
    }
    for(int i=head[x];i!=-1;i=nxt[i])
        if(v[i]!=fa)
            dfs2(v[i],x);
}

int main()
{
    memset(head,-1,sizeof(head));//节点编号从0开始
    int i;
    int x,y;
    n=read();
    for(i=1;i<n;++i)
    {
        x=read(); y=read();
        add(x,y);
        add(y,x);
    }
    dfs(0,-1);
    dfs2(0,-1);
    for(i=0;i<n;i++)
        if(w[i]+d1[i]==ans || d1[i]+d2[i]==ans)
            printf("%d\n",i);
    return 0;
}

 

posted @ 2018-12-08 08:37  白驹过隙----青春绿  Views(140)  Comments(0Edit  收藏  举报