加工树枝

Dragon同学一天捡到了一根非常非常巨大的树枝,于是同学就想啊,如果把这根树枝多余的分叉剔掉最后剩下一根没有分叉的木棍,用它自卫就没人敢欺负我们科学家了呀:)

你的任务是,对给定树枝,求出它包含的最长木棍。

输入文件:

第一行一个正整数n,表示顶点数,顶点从1至n编号(N <= 100000)。

然后n – 1行每行两个正整数u, v表示u, v之间有一条边,每条边的长度为1。

保证输入的是一棵树。

输出文件:

只有一行,表示给定树的最长链长度。

Tree.in

5

1 2

1 3

1 4

1 5

Tree.out

2

 

 f[][1]表示是与当前节点连接的儿子链的最长的长度。

 f[][0]表示当前节点连接起来的最大的值。

#include<cstdio>
#define max 200010
int f[100010][2],n[max],x[max],k[max];
int m,o;
bool v[max];

void dp(int a)
{
    int t;
	v[a]=1;
	f[a][0]=0;
	f[a][1]=0;
	t=k[a];
	while (t)
	{
	    if (!v[x[t]])
		{
		    dp(x[t]);
			if (f[x[t]][1]+f[a][1]>f[a][0]) f[a][0]=f[a][1]+f[x[t]][1]+1;
			if (f[x[t]][0]>f[a][0]) f[a][0]=f[x[t]][0];
			if (f[x[t]][1]>=f[a][1]) f[a][1]=f[x[t]][1]+1;
		}
	    t=n[t];
	}
    if (f[a][1]>f[a][0]) 
	{
		//*(*(f+a)+1)=*(*(f+a));
		f[a][0]=f[a][1];
	}
}

int main()
{
    freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&m);
	int a,b;
	for (int i=1;i<=m;i++)
	{
	    scanf("%d %d",&a,&b);
		x[++o]=b;
		n[o]=k[a];
		k[a]=o;
		x[++o]=a;
		n[o]=k[b];
		k[b]=o;
	}
	dp(1);
	printf("%d\n",f[1][0]);
	return 0;
}