PAT A1021:Deepest Root之DFS求解

题目描述

1021 Deepest Root (25分)
A graph which is connected and acyclic can be considered a tree. The height 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

求解思路

给定结点的个数以及各个结点之间的关系,如果该图是联通的,要求我们给出能够使该树深度最大的根节点(若有多个结点同时满足,按从小到大输出);如果该图并非联通的,要求我们给出连通分量。

  • 使用深度搜索算法,每次都判断当前深度是否大于maxdepth,如果大于的话,则清空能够使树的深度最大的根节点集合之后再将该结点添加到集合中;如果当前深度等于maxdepth,那么直接将该结点加入到集合中。结点处理之后,选择与该结点直接相连的下一个未被遍历过的结点进行遍历。

代码实现(AC)

#include<stdio.h>
#include<vector>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10001; 
int n;	//用于表示结点个数
int cnt=0;	//用于表示连通分量 
int maxdepth=0;	//用于表示树的最大深度
vector<int>edge[maxn];	//用于存储结点之间的关系
vector<int>maxnode;	//用于存储能够使树的深度最大的根节点
set<int>out;	//用于按序且不重复地存储使树的深度最大的根节点 
bool vis[maxn]={false};	//用于记录结点是否被访问过 
void init()
{
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int v1,v2;
		scanf("%d %d",&v1,&v2);
		edge[v1].push_back(v2);
		edge[v2].push_back(v1); 
	}
}
void dfs(int source,int depth)
{
	vis[source]=true;
	if(depth>maxdepth)
	{
		maxdepth=depth;
		maxnode.clear();
		maxnode.push_back(source);	
	}	
	else if(depth==maxdepth)
		maxnode.push_back(source);
	for(int i=0;i<edge[source].size();i++)
	{
		if(!vis[edge[source][i]])
			dfs(edge[source][i],depth+1);
	}
}
void solve()
{
	init();
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			dfs(i,1);
			cnt++;
		}
		if(i==1)
		{
			fill(vis,vis+maxn,false);
			for(int j=0;j<maxnode.size();j++)
				out.insert(maxnode[j]);
			dfs(maxnode[0],1);
		}
	}
	if(cnt==1)
	{
		for(int i=0;i<maxnode.size();i++)
			out.insert(maxnode[i]);
		set<int>::iterator it;
		for(it=out.begin();it!=out.end();it++)
			printf("%d\n",*it);
	}
	else	printf("Error: %d components",cnt);
}
int main()
{
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值