找树的直径的方法其实就是先任取一点进行bfs,找到最远的一点,这时最远的一点肯定是最长链端点之一,然后再从这一最远点开始bfs,这时另一个端点就找到了,长度就是bfs的深度。
这道题目看了别人的才猛然想到对啊,你照的点的最长肯定在你要找的最长的上面。开始还以为是树对树有种莫名其妙的恐惧感。。。。
Description
FF是图论高手,所以我要出图论且不出流问题。
给出一个树,求树的最长链的长度。
Input
多组输入。每组输入的第一行为n(1 <= n <= 100000),代表节点个数,节点编号从1 到n,接下来的n-1行,每行两个正整数u,v,代表u,v之间有一条边相连。保证每组数据都是一棵树。
Output
对于每组数据,输出一个正整数代表答案。
Sample Input
121 2
Sample Output
12
Hint
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<ctype.h>
#include<queue>
using namespace std;
struct node
{
int u,v,next;
} edge[200000];
struct w
{
int step,date;
} t,f;
int cnt,head[200000],vis[200000],p,s;
void add(int u,int v)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void bfs(int b)
{
memset(vis,0,sizeof(vis));
queue<w>q;
t.step=1;
t.date=b;
vis[b]=1;
q.push(t);
while(!q.empty())
{
t=q.front();
q.pop();
p=t.date;
s=t.step;
int u=t.date;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
f.date=edge[i].v;
if(!vis[f.date])
{
f.step=t.step+1;
vis[f.date]=1;
q.push(f);
}
}
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==1)
{
printf("1\n");
continue;
}
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1; i<n; i++)
{
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
bfs(1);
bfs(p);
printf("%d\n",s);
}
return 0;
}