知道【SDOI2011 消防】之后,这就是道水题了。这道题可以参照六号的博客。
求出树的直径并找出树的直径上的点。找出直径上的点子树的最大深度即可。
代码:
#include<cstdio>
#define MAXN 100005
#define MAXM 200005
int N,Ans;
int tot,en[MAXM],nex[MAXM],las[MAXN];
void ADD(int x,int y)
{
en[++tot]=y;
nex[tot]=las[x];
las[x]=tot;
}
int St,En,ID,MaxDis,pre[MAXN];
void FindD(int x,int f,int dis)
{
if(dis>MaxDis)ID=x,MaxDis=dis;
int i,y;
for(i=las[x];i;i=nex[i])
{
y=en[i];
if(y==f)continue;
pre[y]=x;
FindD(y,x,dis+1);
}
}
bool mark[MAXN];
void FindAns(int x,int f,int dis)
{
if(dis>Ans)Ans=dis;
int i,y;
for(i=las[x];i;i=nex[i])
{
y=en[i];
if(y==f||mark[y])continue;
FindAns(y,x,dis+1);
}
}
int main()
{
int i,j,x,y;
scanf("%d",&N);
for(i=1;i<N;i++)
{
scanf("%d%d",&x,&y);
ADD(x,y);ADD(y,x);
}
FindD(1,0,0);MaxDis=0;St=ID;
FindD(St,0,0);En=ID;
pre[St]=0;
for(i=En;i;i=pre[i])mark[i]=true;
for(i=En;i;i=pre[i])FindAns(i,0,0);
printf("%d",Ans);
}