1. 程式人生 > >樹的最長路徑(直徑)【codevs1814】

樹的最長路徑(直徑)【codevs1814】

樹的最長路徑即樹上的最遠點對,也被稱為樹的直徑。

這可以用兩遍dfs來求。第一遍dfs先任選一個點,找出離這個點最遠的點maxd。該點必為最長路徑上的一個端點(可以用反證法證明)再從maxd這個點出發再進行一次dfs就能找到另一個端點。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,cnt,max0,maxd,x,y,maxx[210035],t[210035],head[210035],nxt[210035],to[210035],dep[100035];
void add(int x,int y)
{
	cnt++;nxt[cnt]=head[x];to[cnt]=y;head[x]=cnt;
}
void dfs(int u,int fa)
{
	maxx[u]=dep[u];
	for (int i=head[u];i;i=nxt[i])
	{
		if (to[i]==fa) continue;
		dep[to[i]]=dep[u]+1;
		dfs(to[i],u);
		maxx[u]=max(maxx[u],maxx[to[i]]);
	}
	if (dep[u]>max0) max0=dep[u],maxd=u;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) 
	{
		scanf("%d%d",&x,&y);
		if (x) add(i,x);
		if (x) add(x,i);
		if (y) add(i,y);
		if (y) add(y,i);
	}
	max0=0;
	dfs(1,0);
	memset(dep,0,sizeof(dep));
	max0=0;
	dfs(maxd,0);
	printf("%d\n",max0);
}