PAT1021 Deepest Root
题目地址: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相关推荐
- PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度
文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...
- 1021. Deepest Root (25)
题目链接:http://www.patest.cn/contests/pat-a-practise/1021 题目: 1021. Deepest Root (25) 时间限制 1500 ms 内存限制 ...
- 【分析】1021 Deepest Root (25 分)【DFS解法】
立志用最少的代码做最高效的表达 PAT甲级最优题解-->传送门 A graph which is connected and acyclic can be considered a tree. ...
- 【PAT - 甲级1021】Deepest Root (25分)(并查集,暴力枚举)
题干: A graph which is connected and acyclic can be considered a tree. The height of the tree depends ...
- PTA-1021—— Deepest Root(最后两组数据错误)
题目: A graph which is connected and acyclic can be considered a tree. The hight of the tree depends o ...
- 浙大PAT 1021. Deepest Root (25)
1021. Deepest Root (25) 时间限制 1500 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph ...
- PAT甲级-1021 Deepest Root(25分)
题目:1021 Deepest Root(25分) 分析:找出以某个节点为根时,最深的根,这题可能会超时要用vector来表示二维数组 疑问:代码一是第二次写的超时了,代码二是第一次写的AC了,找不出 ...
- PTA Deepest Root (25分)
释放无限光明的是人心,制造无边黑暗的也是人心,光明和黑暗交织着,厮杀着,这就是我们为之眷恋又万般无奈的人世间. A graph which is connected and acyclic can b ...
- 1021 Deepest Root
要解决两大问题: 1. 数包含几个连通分量 2. 如何找到最深结点 注意:connected components的意思是连通分量 问题1我用并查集解决 问题2转化为如何得到每个结点的深度 值得注意之 ...
最新文章
- java提供密码加密的实现
- Oracle 提示符
- Oracle-存储过程实现更改用户密码
- 前端学习(1734):前端系列javascript之发行
- linux基础知识——CPU相关知识
- 良心推荐丨国庆7天长假,程序员最佳度假去处
- 苹果欺诈性营销?iPad mini 6因“果冻屏”遭用户集体诉讼
- keepalived+lvs+nginx高可用
- WinAPI——钩子函数大全
- [论文阅读] Cascaded Partial Decoder for Fast and Accurate Salient Object Detection
- ArcGIS水文分析实战教程(7)细说流域提取
- Chrome浏览器模拟手机访问网站
- python123反素数_初学python之路-day01
- 任性与自制力差--拖延症(行为训练)
- php halt,thinkphp-调试halt
- android 软键盘弹出内容整体上移,软键盘弹出后布局上移
- 华为android内存扩大,安卓手机运行内存越来越不够用,华为却放出了这一招来解决!...
- 软考英文缩写_计算机软件常见英文缩写及对应全称
- (转载)总结一下SQL语句中引号(')、quotedstr()、('')、format()在SQL语句中的用法...
- caffe-ristretto:定点方案
热门文章
- python 逐行读取文件_Python fileinput模块:逐行读取多个文件
- css3如何链如外部字体,微信小程序引入外部字体总结(针对安卓加载缓慢问题)...
- 联想微型计算机怎么恢复系统,联想电脑台式一体机怎么重装系统 台式一体机重装系统...
- 塔菲尔曲线斜率的大小_中国第一塔,与埃菲尔铁塔齐名,到底有多强悍?
- java虚拟机时区_转:jvm设置时区问题
- Spark cluster 安装
- 会计电算化是对用电子计算机处理,会计电算化的意义是什么
- c语言中最常用的四种数据类型,计算机中有哪几种常见数据类型
- can是什么时候处于显性_CAN总线边沿时间标准是什么?
- Linux操作系统下软件的安装与卸载