PAT甲级--1021 Deepest Root(25 分)【dfs+连通分量+STL】

1021 Deepest Root(25 分)

A graph which is connected and acyclic can be considered a tree. The hight of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤10​4​​) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N−1 lines follow, each describes an edge by given the two adjacent nodes' numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print Error: K components where K is the number of connected components in the graph.

Sample Input 1:

5
1 2
1 3
1 4
2 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components

解题思路:这题说了n-1,就说明要么是树,要么就不是树(这个自己体会噢),我们在存储节点的关系时,是用二维,不过这题2个节点,其中一个节点可以是另一个节点的孩子或者是父亲,我们dfs来寻找最高高度的节点,一旦当前height大于最高高度,那么temp存的都清除掉(temp是存最高高度节点,一旦要更高的就清除,存储新的),存当前的节点,并且将visit置为true,就继续dfs它的孩子(之前没有遍历过的),然后我们从每一个节点访问,dfs(i,1),如果是树,那么我们i=1的时候,所有节点的visit应该都置为true,除非不是树,那么我们就统计一下分成多少块,如果==1的话就说明树,那我们就将dfs(1,1)的最高高度节点作为dfs的开始(就相当于你把一些东西串成树的结构,找到最底下那一层,随便拎最下面的一个点,它的高度就会是最高的,反过来之前从dfs(1,1)的最高高度的点也是最高的,就是一头一尾的都是最高的,可能没有表达的很清楚,但是你慢慢地就会理解的)下面的代码我注释了一点,理解代码会更方便一点。

#include<bits/stdc++.h>
using namespace std;
int maxheight=0;//初始化最高高度为0
bool visit[10010];//判断有没有遍历过
set<int>s;//set容器,没有重复元素,并且有序,默认从小到大
vector<vector<int> >v;//存储边,相当于二维数组
vector<int>temp;//临时存储最高的节点
void dfs(int root,int height)
{
	if(height>maxheight)
	{
		maxheight=height;
		temp.clear();
		temp.push_back(root); 
	}
	else if(maxheight==height)
	{
		temp.push_back(root);
	}
	visit[root]=true;
	for(int i=0;i<v[root].size();i++)
	{
		if(visit[v[root][i]]==false)
		dfs(v[root][i],height+1);
	}
}
int main(void)
{
	int a,b,n;
	scanf("%d",&n);
	v.resize(n+1);//一定要初始化,要不然输不进去数据 
	for(int i=0;i<n-1;i++)//是n-1条边,一开始不小心写成了n,导致答案输不出来 
	{
		scanf("%d %d",&a,&b);//a是父亲或者孩子
		v[a].push_back(b);
		v[b].push_back(a);
	}
	int cnt=0,s1=0;
	for(int i=1;i<=n;i++)
	{
		if(visit[i]==false)//如果是树,那么i=1的时候,所有节点都遍历过,除非不连通
		{
			dfs(i,1);
			if(i==1)
			{
				if(temp.size()!=0) s1=temp[0];
				for(int j=0;j<temp.size();j++)
				s.insert(temp[j]);
			}
			cnt++;
		}
	}
	if(cnt>=2) printf("Error: %d components",cnt);
	else
	{
		temp.clear();
		fill(visit,visit+10010,false);//是树,然后所有节点都赋值为false
		dfs(s1,1); //等于1时最高高度的节点,随便选一个来dfs,找出其他最高高度的节点,一头一尾的都是最高
		for(int i=0;i<temp.size();i++)
		s.insert(temp[i]);
    	        for(auto it = s.begin(); it != s.end(); it++)//set容器是有序的
                printf("%d\n", *it);
	}
	return 0;
} 

 

展开阅读全文

没有更多推荐了,返回首页