tyvj4865 天天和树tree

#include<bits/stdc++.h>
#define MAXN 100000+10
using namespace std;
struct ed{int v,next;}edge[2*MAXN];
int n,far1,far2,maxlen,ans=0,head[MAXN],pre[MAXN],d[MAXN];
bool is[MAXN],vis[MAXN];
void add(int u,int v){
    static int tot=0;
    edge[++tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot;
}
void dfs1(int u,int fa,int len){
    if(len>maxlen){maxlen=len;far1=u;}
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].v;
        if(v!=fa)dfs1(v,u,len+1);
    }
}
void dfs2(int u,int fa,int len){
    pre[u]=fa;
    if(len>maxlen){maxlen=len;far2=u;}
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].v;
        if(v!=fa)dfs2(v,u,len+1);
    }
}
void dfs3(int u,int fa,int dis){
    d[u]=dis;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].v;
        if(v!=fa)dfs3(v,u,dis+1);
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    maxlen=0;
    dfs1(1,1,1);
    maxlen=0;
    dfs2(far1,far1,1);
    is[far1]=1;
    for(int i=far2;i!=pre[i];i=pre[i])is[i]=1;
    for(int u=1;u<=n;u++)
        if(is[u]){
            for(int i=head[u];i;i=edge[i].next){
                int v=edge[i].v;
                if(!is[v])dfs3(v,u,1);
            }
        }    
    for(int i=1;i<=n;i++)
        if(!is[i])ans=max(ans,d[i]);
    printf("%d",ans);        
    return 0;
}

 

找直径即可,正确性显然(嘿嘿嘿。。。)

 其实反证法很容易搞定。。。。

posted @ 2017-09-19 22:05  NINGLONG  阅读(142)  评论(0编辑  收藏  举报