九度1536

这题的话其实是为了说明一个算是比较重要的结论把,假如我要找一棵树中距离最远的两个点,我可以这么找,首先任取一点bfs找到离这点最远的那个点,然后从被找到的这个点出发,再一遍bfs找到离刚找的这点最远的点,那么这两点的距离一定是树中距离最大的,但显然不唯一。这 题让你求树的最小高度,假如我们求出了树中最大的距离L,那么如果我们要在最长路径中选择一个点作为根,显然这个根就是选在中点,最小高度是(L+1)/2,其实为了得到最小高度,我们的做法就是使最大的距离最小,就是尽量地取平均。对于其他点,他们基于最大的距离最小的思想后,产生 的距离是不会大于(L+1)/2的,所以,其实(L+1)/2就是答案了。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a[1000001];
vector<int>::iterator it;
int q[1000001][2];
int mark[1000001];
int n;
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int i;
		if(n==1)
		{
			printf("0\n");
			continue;
		}
		for(i=0;i<n;i++)
			a[i].clear();
		for(i=1;i<=n-1;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			a[x].push_back(y);
			a[y].push_back(x);
		}

		memset(q,0,sizeof(q));
		memset(mark,0,sizeof(mark));
		int max=0;
		int l,r;
		l=0,r=1;
		q[0][0]=0;
		q[0][1]=0;
		mark[0]=1;
		
		int st;
		while(l<r)
		{
			int tmp=q[l][0];
			for(i=0;i<a[tmp].size();i++)
			{
				int kk=a[tmp][i];
				if(mark[kk]==0)
				{
					mark[kk]=1;
					q[r][0]=kk;
					q[r][1]=q[l][1]+1;
					if(max<q[r][1])
					{
						max=q[r][1];
						st=kk;
					}
					r++;
				}
			}
			l++;
		}
		
		memset(q,0,sizeof(q));
		memset(mark,0,sizeof(mark));
		l=0,r=1;
		q[0][0]=st;
		q[0][1]=0;
		mark[st]=1;
		max=0;
		while(l<r)
		{
			int tmp=q[l][0];
			for(i=0;i<a[tmp].size();i++)
			{
				int kk=a[tmp][i];
				if(mark[kk]==0)
				{
					mark[kk]=1;
					q[r][0]=kk;
					q[r][1]=q[l][1]+1;
					if(max<q[r][1])
						max=q[r][1];
					r++;
				}
			}
			l++;
		}
		printf("%d\n",(max+1)/2);
		
	}
	return 0;
}




你可能感兴趣的:(树,bfs)