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
 #include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int G[][];
int father[];
int maxDepth = -;
int N;
vector<int> temp_, ans;
void dfs(int vt, int from, int level){
level++;
if(maxDepth < level){
maxDepth = level;
temp_.clear();
temp_.push_back(vt);
}else if(maxDepth == level){
temp_.push_back(vt);
}
for(int i = ; i <= N; i++){
if(G[vt][i] == && i != from){
dfs(i, vt, level);
}
}
}
int findFather(int vt){
int temp = vt;
while(vt != father[vt]){
vt = father[vt];
}
int temp2;
while(temp != vt){
temp2 = father[temp];
father[temp] = vt;
temp = temp2;
}
return vt;
}
int main(){
scanf("%d", &N);
int tempA, tempB;
int root1, root2;
for(int i = ; i <= N; i++){
father[i] = i;
}
for(int i = ; i < N - ; i++){
scanf("%d%d", &tempA, &tempB);
G[tempA][tempB] = G[tempB][tempA] = ;
root1 = findFather(tempA);
root2 = findFather(tempB);
if(root1 != root2)
father[root2] = root1;
}
int cnt = ;
for(int i = ; i <= N; i++){
if(father[i] == i)
cnt++;
}
if(cnt > ){
printf("Error: %d components\n", cnt);
}else{
maxDepth = -;
dfs(, -, );
ans = temp_;
temp_.clear();
maxDepth = -;
dfs(ans[], -, );
for(int i = ; i < temp_.size(); i++)
ans.push_back(temp_[i]);
sort(ans.begin(), ans.end());
printf("%d\n", ans[]);
for(int i = ; i < ans.size(); i++){
if(ans[i] != ans[i - ])
printf("%d\n", ans[i]);
}
}
cin >> N;
return ;
}

总结:

1、题意:给出一个可能是树的图,要求找到root(可能多个),使得从root出发可以使树的高度最高。但如果给出的图不是树(因为N个顶点 N - 1条边,如果产生回路只能说明输入的图不是一个连通图),要求输出连通分量的个数。 起初没注意到N个节点 N - 1条边这个条件,没有搞清楚题意,还以为判断是否是树是通过判断图里有没有回路来进行的,莫名奇妙为什么不是树之后就要求联通分量。于是还通过找回路来判断是否是树,结果当然不对。

2、求连通分量首选并查集,如果两个点是联通的就把它们并为一个集合。在读入边的时候就可以做合并,结束之后计数father[ i ] = i 的节点个数就行了。其次可以借助深搜广搜配合visit数组,在遍历完每一个点,检查下一个点的visit为0的即作为一个连通分量。显然,当输入的图连通分量大于1时说明不是树。

3、找能使得树最高的root方法:先随便找一个点A,从它开始做一遍dfs并在过程中将level最大的节点全部保存。这些节点就是答案的一部分,但还存在遗漏。再从已经选出的root中随意选择一个B,从它开始遍历一遍dfs并保存level最大的节点,两部分并起来就是最终答案。(没看书之前我是暴力破解,把所有节点遍历一次以找到最大深度的根,结果有一个测试点超时)

4、visit数组:平时做bfs使用visit数组标记节点是否曾经加入过队列,做dfs标记节点是否被访问过,其实都是为了防止重复访问节点。但本题中一旦确定了是一棵树,说明不存在回路,则可以不需要visit数组。但在无向图中仍然需要一个变量保存上一次访问过的节点,以防止同一条边上的重复访问。比如节点A、B在一条边上,A->B访问结束,到B之后B的联通的节点中又会有A,造成再次访问A(用孩子法存储的树无需考虑该问题,但用图的形式存储的树必须考虑同一条边的重复访问)。

5、找回路:利用visit数组与上次访问节点的序号即可。在碰到一个与当前节点相连接、不是上一次访问过的再同一条边上的节点、visit数组为1,则存在回路。

6、sort的默认排序是从小到大。

A1021. Deepest Root的更多相关文章

  1. PAT A1021 Deepest Root (25 分)——图的BFS,DFS

    A graph which is connected and acyclic can be considered a tree. The hight of the tree depends on th ...

  2. PAT甲级——A1021 Deepest Root

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

  3. PAT Advanced A1021 Deepest Root (25) [图的遍历,DFS,计算连通分量的个数,BFS,并查集]

    题目 A graph which is connected and acyclic can be considered a tree. The height of the tree depends o ...

  4. [PAT] A1021 Deepest Root

    [题目大意] 给出n个结点和n-1条边,问它们能否形成一棵n个结点的树,如果能,从中选出结点作为树根,使整棵树的高度最大.输出所有满足要求的可以作为树根的结点. [思路] 方法一:模拟. 1 连通.边 ...

  5. PAT_A1021#Deepest Root

    Source: PAT A1021 Deepest Root (25 分) Description: A graph which is connected and acyclic can be con ...

  6. 1021.Deepest Root (并查集+DFS树的深度)

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

  7. 1021. Deepest Root (25) -并查集判树 -BFS求深度

    题目如下: A graph which is connected and acyclic can be considered a tree. The height of the tree depend ...

  8. PAT1021:Deepest Root

    1021. Deepest Root (25) 时间限制 1500 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph ...

  9. 1021. Deepest Root (25)

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

随机推荐

  1. 【git】如何去解决fatal: refusing to merge unrelated histories

    我在Github新建一个仓库,写了License,然后把本地一个写了很久仓库上传. 先pull,因为两个仓库不同,发现refusing to merge unrelated histories,无法p ...

  2. python之路--管道, 事件, 信号量, 进程池

    一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...

  3. GIT的前世今生

    在重点介绍GIT的一些操作之前,我们首先来说一说GIT的前世今生,了解整个版本控制的变迁能够让我们知道该如何去选择这些工具,另外通过这些技术的变迁也能够让我们对现在的技术有着更加深入的理解,在正式介绍 ...

  4. Navicat Preminum

    此软件在连接的时候,需要这样: 新建链接==>连接属性==>编码选择自动==>如果此时点击确定的话,会把整个服务器的所有数据库都打开, 我们也可以只打开指定的数据库, 点击高级==& ...

  5. 刪除nodejs

    https://www.cnblogs.com/fighxp/p/7410235.html https://www.cnblogs.com/fighxp/p/7411608.html

  6. ADO.NET工具类(三)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  7. Android 模块化/热修复/插件化 框架选用

    概念汇总 动态加载:在程序运行的时候,加载一些程序自身原本不存在的文件并运行这些文件里的代码逻辑.动态加载是热修复与插件化实现的基础. 热修复:修改部分代码,不用重新发包,在用户不知情的情况下,给ap ...

  8. 基于jQuery-ui实现多滑块slider

    效果图: 代码: <!doctype html> <html lang="en"> <head> <meta charset=" ...

  9. BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点

    题目描述 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过 ...

  10. Codeforces Round #507 Div. 1

    D:类似于noip2018d1t3,子树内的链应该贪心的尽量合并而不是拆开.则设f[i]为i子树内满足选的链尽量多的情况下根所在的链的最长长度即可.于是可以线性对某个k求得答案. 注意到长度为k的链不 ...