1. 程式人生 > >小米筆試題:樹的高度

小米筆試題:樹的高度

題目連結:樹的高度

用並查集的方法做的。
這個題不是表述有問題,就是測試資料有問題。題目說了是合法的二叉樹,但是測試資料是有多叉樹的。
要把多餘的樹枝砍掉,就是說如果這個結點出現了第三個孩子,我們就不要去考慮第三個孩子。
並查集的思路就是構造出這麼一棵樹,然後如果出現第三個孩子及以上,把它標記出來,搜尋的時候,搜尋到這個孩子的時候就認為不合法。

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e6+5;
int fa[maxn];
int child[maxn];
int vis[maxn];
int dfs(int i); 
void init()				//初始化 
{
	for(int i=0;i<maxn;++i)
	{
		fa[i]=i;		//一開始讓所有的節點都做自己的父親 
		child[i]=0;		//表示這個節點有多少個孩子 
		vis[i]=0;		//1表示這個節點是不合法的,0表示是合法的 
	}
}
void join(int x,int y)	//x是y的父親 
{
	child[x]++;			//x的孩子數加1 
	if(child[x]>=3)		//如果孩子的節點數大於等於3,則表示這個孩子不合法 
	{
		vis[y]=1;		//因為不合法,所以標記一下 
		return ;
	}
	fa[y]=x;			//讓y的父親是x 
	return ;
}
int main()
{
	int n,x,y;
	while(cin>>n)
	{
		init();
		for(int i=0;i<n-1;i++) 
		{
			cin>>x>>y;
			join(x,y);	
		}
		int big_num=0,a;		//big_num表示樹的高度,a表示每個節點的高度 
		for(int i=0;i<n-1;i++)
		{
			a=dfs(i);
			big_num=big_num>a?big_num:a;	//如果這個節點比以前的都大,則更新答案 
		}
		cout<<big_num<<endl;
	}
	return 0;
}
int dfs(int i)			//對i這個節點進行搜尋 
{
	int tree_len=1;		//初始化該節點的高度為1 
	int t=i;
	while(t!=fa[t])		//如果t不是根節點本身 
	{
		t=fa[t];		//則訪問它的父親節點 
		tree_len++;		//樹的長度+1 
	}
	if(vis[t]) return 0;//如果該節點不合法,直接返回長度0 
 	return tree_len;	
}