PAT A 1021 Deepest Root (25 分)

1021 Deepest Root (25 分)

题意(意会版)

N个点,两两连了N-1条线,变成了一张图。这张图里要是没有成环的部分而且全部点都连在一起,就可以被看成一个树。
给你N个点和N-1条线,问你这个图:
①是不是树(是不是没有成环/全图连通)(这两个是一个概念。N个点N-1条线,有环必分块,分块必有环。);
②是树的话,给出最长的那些路的两端的标号;
③不是树的话,给出分成了几块。

逻辑

建立图;
从每个叶子 (度为1)(树是单向所以叶子是度0,但这是个图so)开始广度优先搜索其他点,找出最长路径长度,记录在这个点里。 ——对于树来说确实如此,然而对于测点2那种情况就炸了(见“关于测试点”);
从每个节点开始广度优先搜索(广度优先遍历)其他点,找出最长路径长度,记录在这个点里;

  • 如果这时候发现有点没跑到,说明这图不是树,那就不用管什么长度了。接下来对剩下没跑到的点跑搜索,再看有没有还没跑到的,有就再跑。加上最开始那次,跑几次就有几个块,输出。
  • 如果都跑到了,那OK。找到最长路径长度最长的那些节点输出即可。

关于测试点

二号点是关于多个连通块的……而且考虑我的修改逻辑,这个测点里大概没有只有一个度的节点……要么是0要么大于等于2。

题目

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

代码

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

typedef struct Node
{
	vector<int> c;
	int edge = 0;
	int maxheight = 0;
}node;

node* nodes;

int* floors;

void FS(int n, int f);

int main()
{
	int n;
	cin >> n;
	nodes = new node[n + 1];
	int tempi, tempii;
	for (int i = 0; i < n - 1; i++)
	{
		cin >> tempi >> tempii;
		nodes[tempi].c.push_back(tempii);
		nodes[tempii].c.push_back(tempi);
		nodes[tempi].edge++;
		nodes[tempii].edge++;
	}
	floors = new int[n + 1]{ -1 };
	int max;
	for (int i = 1; i < n + 1; i++)
	{
		
			max = 0;
			fill(floors, floors + n + 1, -1);
			floors[i] = 0;
			FS(i, 0);
			for (int ii = 1; ii < n + 1; ii++)
			{
				if (floors[ii] == -1)
				{
					int count = 1;
					for (int iii = 1; iii < n + 1; iii++)
					{
						if (floors[iii] == -1)
						{
							floors[iii] = 0;
							FS(iii, 0);
							count++;
						}
					}
					cout << "Error: " << count << " components";
					return 0;
				}
				if (floors[ii] > max)
					max = floors[ii];
			}
			nodes[i].maxheight = max;
	}
	max = 0;
	for (int i = 1; i < n + 1; i++)
	{
		if (nodes[i].maxheight > max)
			max = nodes[i].maxheight;
	}
	for (int i = 1; i < n + 1; i++)
	{
		if (nodes[i].maxheight == max)
			cout << i << endl;
	}
	return 0;
}

void FS(int n,int f)
{
	floors[n] = f;
	int i;
	int tempi;
	for (i = 0; i < nodes[n].c.size(); i++)
	{
		tempi = *(nodes[n].c.begin() + i);
		if (floors[tempi] == -1)
			FS(tempi, f + 1);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值