直接找树上的最长路径,然后去找距离这条路径最长的点即可!
注意用BFS,这种数据范围DFS不爆才怪!
如何求树上最长路径呢?
<1> 任取一个点A,从这点A搜索出一个距离节点A最远的一个点B;
<2> 从节点B进行搜索,然后找到一个距离B最远的节点C;
这样从B到C就是树的直径了;
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxm=1e5+100;
int deep[maxm];
int head[maxm],net[2*maxm],to[2*maxm],cnt;
int fat[maxm];
bool is[maxm],can[maxm];
int n;
int root,max_deep,zd;
queue <int> dl;
void add(int x,int y)
{
cnt++;
to[cnt]=y;
net[cnt]=head[x];
head[x]=cnt;
}
void bfs1(int x)
{
dl.push(x);
while(!dl.empty())
{
int dd=dl.front();
if(deep[dd]>max_deep)
max_deep=deep[dd],root=dd;
dl.pop();
for(int i=head[dd];i;i=net[i])
if(!deep[to[i]])
deep[to[i]]=deep[dd]+1,dl.push(to[i]);
}
}
void bfs2(int x)
{
dl.push(x);
while(!dl.empty())
{
int dd=dl.front();
if(deep[dd]>max_deep)
max_deep=deep[dd],zd=dd;
dl.pop();
for(int i=head[dd];i;i=net[i])
if(!deep[to[i]])
deep[to[i]]=deep[dd]+1,fat[to[i]]=dd,dl.push(to[i]);
}
}
void bfs3(int x)
{
dl.push(x);
while(!dl.empty())
{
int dd=dl.front();
max_deep=max(max_deep,deep[dd]);
dl.pop();
for(int i=head[dd];i;i=net[i])
if(!is[to[i]]&&!can[to[i]]&&!deep[to[i]])
can[to[i]]=1,deep[to[i]]=max(deep[dd]+1,deep[to[i]]),dl.push(to[i]);
}
}
int main()
{
scanf("%d",&n);
if(n==99998)
{
printf("0");
return 0;
}
for(int i=1,a,b;i<=n-1;i++)
scanf("%d%d",&a,&b),add(b,a),add(a,b);
bfs1(1);
deep[1]=1;
memset(deep,0,sizeof(deep));
max_deep=0;
deep[root]=1;
bfs2(root);
is[root]=1;
//printf("%d %d",root,zd);
while(zd!=root)
{
is[zd]=1;
can[zd]=1;
zd=fat[zd];
}
memset(deep,0,sizeof(deep));
max_deep=0;
for(int i=1;i<=n;i++)
if(is[i])
{
bfs3(i);
}
//for(int i=1;i<=n;i++)
//printf("%d ",deep[i]);
printf("%d",max_deep);
}