【PAT】1021. Deepest Root (25)

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 (<=10000) 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
分析:题目要求一个DFS;判断可用并查集或用图;排序习惯用优先队列
细节:主要考察代码熟练度
 
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <functional>
using namespace std;

const int Max=10001;
priority_queue<int, vector<int>, greater<int> > q;

class Ver
{
	public:
		int info;
		vector<int> link;
		int num;	
		Ver(){
			num=0;
		}
		Ver(int x){
			info = x;
		}
}ver[Max];

class graph
{
	public:
		int numver;
		int numedge;
		int visited[Max];
		graph();
		void insertVer(int x);
		void insertEdge(int x, int y);
		int getedge(int v, int x);
		int DFS(int v, int h);
};

graph::graph(){
	numver=numedge=0;
	for (int i=0;i<Max;++i){
		visited[i]=0;
	}
}

void graph::insertVer(int x){
	ver[x].info=x;
	++numver;
}

void graph::insertEdge(int x, int y){
	ver[x].link.push_back(y) ;
	ver[y].link.push_back(x);
	++ver[x].num;
	++ver[y].num;
	++numedge;
}

int graph::getedge(int v, int x)
{
	return ver[v].link[x];
}

int graph::DFS(int x, int h)
{
	visited[x]=1;
	int tmp=h;
	for (int i=0;i<ver[x].num;++i){
		int w=getedge(x,i);
		if (visited[w]!=1){
			int t=DFS(w,h+1);
			if (tmp<t) tmp=t;
		}
	}
	return tmp;
}

int main()
{
//	freopen("test.txt","r",stdin);
	graph g;
	int n;
	cin>>n;
	for (int i=1;i<=n;++i){
		g.insertVer(i);
	}
	for (int i=1;i<n;++i){
		int x,y;
		cin>>x>>y;
		g.insertEdge(x,y);
	}
	int flag=0;
	for (int i=1;i<=n;++i){
		if (g.visited[i]==0){
			++flag;
			g.DFS(i,0);
		}
	}
	if (flag!=1) printf("Error: %d components\n",flag);
	else{
		int tmp=0;
		for (int i=1;i<=n;++i){
			for (int j=1;j<=g.numver;++j) g.visited[j]=0;
			int t=g.DFS(i,0);
			if (t>tmp){
				tmp=t;
				while (!q.empty()) q.pop();
				q.push(i);
			}
			else if (t==tmp) q.push(i);			
		}
		while (!q.empty()){
			printf("%d\n",q.top());
			q.pop();
		}
	}
	
	return 0;
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值