题意:幻想乡有一个赛车场。赛车场里有N个地点。同时地点之间还有单向的道路存在。
这些道路使得赛车场形成了一个外向树的结构。也就是说,道路将这N个地点连成了一个有根树。并且所有的边都是从父亲指向孩子的。
由于幽香喜欢刺激,每次她去赛车场都会从根节点出发,选择最长的一条路径来玩。
但是现在幽香感觉最长的路径还是太短了,她打算在赛车场里新建一条道路使得新的最长路径最长。
同时,如果道路形成了一个环,那么可能会出现交通事故,所以幽香新建的道路不能导致环的出现。
你能帮幽香算出新建一条道路后的最长路径吗?幽香知道根节点一定是1号点。

先求出最远的那个点,当然那个点肯定是叶子节点,然后再枚举其他叶子节点,计算从那个点到这个叶子节点能走的距离,要计算那个叶子节点和当前叶子节点的LCA,然后计算下距离加起来就行了。。

//author: CHC
//First Edit Time: 2015-08-30 20:10
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
using namespace std;
typedef long long LL;
const int MAXN=100000+1000;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
struct Edge {
int to,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}e[MAXN<<1];
int head[MAXN],tot;
int fa[MAXN][22],dis[MAXN],d[MAXN];
void init(){
memset(head,-1,sizeof(head));
tot=0;
}
void AddEdge(int u,int v){
e[tot]=Edge(v,head[u]);
head[u]=tot++;
}
void dfs(int cur,int f){
for(int i=1;i<=20;i++)
fa[cur][i]=fa[fa[cur][i-1]][i-1];
for(int i=head[cur];~i;i=e[i].next){
int to=e[i].to;
if(to==f)continue;
dis[to]=dis[cur]+1;
d[to]=d[cur]+1;
fa[to][0]=cur;
dfs(to,cur);
}
}
int lca(int a,int b){
if(d[a]<d[b])swap(a,b);
int x=d[a]-d[b],y=0;
while(x){
if(x&1)a=fa[a][y];
x>>=1;
++y;
}
if(a==b)return a;
for(int i=19;i>=0;i--){
if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
}
return fa[a][0];
}
int chu[MAXN];
int main()
{
int n;
while(~scanf("%d",&n)){
init();
memset(chu,0,sizeof(chu));
for(int i=1,x,y;i<n;i++){
scanf("%d%d",&x,&y);
AddEdge(x,y);
++chu[x];
}
fa[1][0]=1;
dis[1]=0;
d[1]=0;
dfs(1,-1);
int maxn=0,maxu=1;
for(int i=1;i<=n;i++){
if(chu[i]==0&&dis[i]>maxn){
maxn=dis[i];
maxu=i;
}
}
int ans=maxn;
for(int i=1;i<=n;i++){
if(chu[i]==0&&maxu!=i){
int v=lca(maxu,i);
ans=max(ans,maxn+dis[i]-dis[v]);
}
}
printf("%d\n",ans);
}
return 0;
}