题目地址:here

题目大意:无环连通图也可以视为一棵树,选定图中任意一点作为根,如果这时候整个树的深度最大,该点称为 deepest root。 给定一个图,按升序输出所有 deepest root。如果给定的图有多个连通分量,则输出连通分量的数量。

解法:先任选一点A从该点开始dfs,找出距离该点最远的点B,则B是一个deepest root;然后从B点开始dfs,找到距离B最远的所有点,这些点加上B点都是deepest root。对于有多个连通分支的,我们可以通过遍历完所有节点调用dfs函数的次数来判断(当然也可以用并查集来求连通分支数目)。                                                                                本文地址

主要是解法中前半段的证明,为什么距离A最远的B是deepest root:

  • 一个概念,定义从deepest root到其最远叶子的路径为树的 “最长路径”
  • 两条最长路径一定有个交点,可以用反证法证明:如果没有交点,由于一棵树中,任意两点都是连通的,可以通过对两条路径组合出一条更长的路径,这与两条路径是最长的矛盾。
  • 假设从A点dfs后,最远的点是B, 假设某一个距离A更近的点D也是deepest root,那么以B、D为端点的最长路径一定有一个交点,假设该交点为k,则有两种情况:(1)最长路径为B....k....D,这种情况和假设不矛盾(2)最长路径为B....k.... 和 D....k....,k后面的路径长度相同。由于A到k一定有一条路径,那么各点之间的关系可以是A...K....D, A....K....B  或者K...A....D,  K...A....B 由于len(A...B)>len(A....D),两种情况下都有:len(B....K) > len(D....K),即len(B....K....) > len(D....K....) 这和D....k....是最长路径矛盾

注意:本题的输入图是默认没有环的

代码如下:                                                                                                             本文地址

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 //本题无向图中默认是没有环的
 8 //先任选一点A从该点开始dfs,找出距离该店最远的点B
 9 //然后从B点dfs,找到距离B最远的所有点,这些点加上B点都是deepest root
10
11 //用邻接表存储图
12 struct GraphNode
13 {
14     vector<int> adja;
15 };
16
17 bool *visited;
18 GraphNode *graph;
19
20 //从某个节点开始深度优先遍历图,并求出相应的树的高度,而且保存离树根最远的节点
21 void dfs(int rootIndex, int level, int &height, vector<int> &farthestNode)
22 {
23     visited[rootIndex] = true;
24     if(height < level)
25     {
26         height = level;
27         farthestNode.clear();
28         farthestNode.push_back(rootIndex);
29     }
30     else if(height == level)
31         farthestNode.push_back(rootIndex);
32     for(int i = 0; i < graph[rootIndex].adja.size(); i++)
33     {
34         int son = graph[rootIndex].adja[i];
35         if(visited[son] == false)
36             dfs(son, level+1, height, farthestNode);
37     }
38 }
39 int main()
40 {
41     int N;
42     scanf("%d", &N);
43     if(N == 1){printf("1"); return 0;}
44     graph = new GraphNode[N+1];
45     visited = new bool[N+1];
46     for(int i = 1; i <= N-1; i++)
47     {
48         int a,b;
49         scanf("%d%d", &a, &b);
50         graph[a].adja.push_back(b);
51         graph[b].adja.push_back(a);
52     }
53     vector<int> farthestNode;
54     int height = 0, components = 0;
55     memset(visited, 0, sizeof(bool)*(N+1));
56     //通过dfs遍历整个图来计算图的连通分支,调用dfs的次数就是连通分支数目
57     for(int i = 1; i <= N; i++)
58         if(visited[i] == false)
59         {
60             visited[i] == true;
61             dfs(i, 0, height, farthestNode);
62             components++;
63         }
64     if(components > 1)
65         printf("Error: %d components",components);
66     else
67     {
68         int k = farthestNode[0];
69         farthestNode.clear();
70         height = 0;
71         memset(visited, 0, sizeof(bool)*(N+1));
72         dfs(k, 0, height, farthestNode);
73         farthestNode.push_back(k);
74         sort(farthestNode.begin(), farthestNode.end());
75         for(int i = 0; i < farthestNode.size(); i++)
76             printf("%d\n", farthestNode[i]);
77     }
78     return 0;
79 }

 【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3401764.html

转载于:https://www.cnblogs.com/TenosDoIt/p/3401764.html

PAT1021 Deepest Root相关推荐

  1. PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度

    文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...

  2. 1021. Deepest Root (25)

    题目链接:http://www.patest.cn/contests/pat-a-practise/1021 题目: 1021. Deepest Root (25) 时间限制 1500 ms 内存限制 ...

  3. 【分析】1021 Deepest Root (25 分)【DFS解法】

    立志用最少的代码做最高效的表达 PAT甲级最优题解-->传送门 A graph which is connected and acyclic can be considered a tree. ...

  4. 【PAT - 甲级1021】Deepest Root (25分)(并查集,暴力枚举)

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

  5. PTA-1021—— Deepest Root(最后两组数据错误)

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

  6. 浙大PAT 1021. Deepest Root (25)

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

  7. PAT甲级-1021 Deepest Root(25分)

    题目:1021 Deepest Root(25分) 分析:找出以某个节点为根时,最深的根,这题可能会超时要用vector来表示二维数组 疑问:代码一是第二次写的超时了,代码二是第一次写的AC了,找不出 ...

  8. PTA Deepest Root (25分)

    释放无限光明的是人心,制造无边黑暗的也是人心,光明和黑暗交织着,厮杀着,这就是我们为之眷恋又万般无奈的人世间. A graph which is connected and acyclic can b ...

  9. 1021 Deepest Root

    要解决两大问题: 1. 数包含几个连通分量 2. 如何找到最深结点 注意:connected components的意思是连通分量 问题1我用并查集解决 问题2转化为如何得到每个结点的深度 值得注意之 ...

最新文章

  1. java提供密码加密的实现
  2. Oracle 提示符
  3. Oracle-存储过程实现更改用户密码
  4. 前端学习(1734):前端系列javascript之发行
  5. linux基础知识——CPU相关知识
  6. 良心推荐丨国庆7天长假,程序员最佳度假去处
  7. 苹果欺诈性营销?iPad mini 6因“果冻屏”遭用户集体诉讼
  8. keepalived+lvs+nginx高可用
  9. WinAPI——钩子函数大全
  10. [论文阅读] Cascaded Partial Decoder for Fast and Accurate Salient Object Detection
  11. ArcGIS水文分析实战教程(7)细说流域提取
  12. Chrome浏览器模拟手机访问网站
  13. python123反素数_初学python之路-day01
  14. 任性与自制力差--拖延症(行为训练)
  15. php halt,thinkphp-调试halt
  16. android 软键盘弹出内容整体上移,软键盘弹出后布局上移
  17. 华为android内存扩大,安卓手机运行内存越来越不够用,华为却放出了这一招来解决!...
  18. 软考英文缩写_计算机软件常见英文缩写及对应全称
  19. (转载)总结一下SQL语句中引号(')、quotedstr()、('')、format()在SQL语句中的用法...
  20. caffe-ristretto:定点方案

热门文章

  1. python 逐行读取文件_Python fileinput模块:逐行读取多个文件
  2. css3如何链如外部字体,微信小程序引入外部字体总结(针对安卓加载缓慢问题)...
  3. 联想微型计算机怎么恢复系统,联想电脑台式一体机怎么重装系统 台式一体机重装系统...
  4. 塔菲尔曲线斜率的大小_中国第一塔,与埃菲尔铁塔齐名,到底有多强悍?
  5. java虚拟机时区_转:jvm设置时区问题
  6. Spark cluster 安装
  7. 会计电算化是对用电子计算机处理,会计电算化的意义是什么
  8. c语言中最常用的四种数据类型,计算机中有哪几种常见数据类型
  9. can是什么时候处于显性_CAN总线边沿时间标准是什么?
  10. Linux操作系统下软件的安装与卸载