1021. Deepest Root (25) -并查集判树 -BFS求深度
题目如下:
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
这个题有N个顶点,N-1条边,属于稀疏图,应该用邻接矩阵而不是邻接表,否则会内存超限。
刚开始拿到这道题目的时候我想到的方法是用带颜色标记的BFS判断环路,并且排除掉,但是这样会超时,后来在网上查阅,看到大家都是使用并查集来判断是否是树,通过把所有元素归入并查集,并且在查询根的时候压缩路径,如果所有元素都是同根的,那么把他们加入Set后集合的规模为1,说明是一棵完整的树,如果不是如此,则说明图由多个连通的部分组成,连通部分的个数等于根的个数,因此只需要输出Set的规模即可。
如果是一棵树,只需要使用BFS来遍历树中的每一个顶点,来计算深度。
为了计算深度,改进BFS,加入三个变量:head、last、tail,last表示这一层的最后一个元素,tail表示下一层的某个元素,初始化时,让last=s,代表第一层只有源点,接下来在出队一个结点,并让head等于这个结点,然后在遍历结点的邻接点时不断的更新tail,不难看出tail在最后一次更新后指向的是下一层的最后一个元素,然后判断head是否等于last,如果是代表本层结束,把层计数变量+1,更新last为tail,以此类推即可。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <set> using namespace std; #define MAX 10002 bool visited[MAX];
vector<vector<int> > Graph;
int N;
int P[MAX]; void initSet(int N){ for(int i = 1; i <= N; i++) P[i] = i; } void CompressSet(int x, int top){ if(P[x] != top){
CompressSet(P[x],top);
P[x] = top;
} } int FindSet(int x){ if(x != P[x]){
int t = FindSet(P[x]);
CompressSet(x,t);
}
return P[x]; } void UnionSet(int x, int y){ int p1 = FindSet(x);
int p2 = FindSet(y);
P[p1] = p2; } int BFS(int s){ for(int i = 1; i <= N; i++) visited[i] = false;
int head,tail,last;
int stage = 0;
queue<int> Q;
Q.push(s);
visited[s] = 1;
last = s;
while(!Q.empty()){
int v = Q.front();
visited[v] = 1;
head = v;
Q.pop();
for(int index = 0; index < Graph[v].size(); index++){
int w = Graph[v][index];
if(!visited[w]){
Q.push(w);
tail = w;
}
}
if(head == last){
last = tail;
stage++;
} } return stage; } int main()
{
cin >> N;
int v1,v2; Graph.resize(N + 1);
initSet(N);
for(int i = 1; i <= N; i++){
visited[i] = false;
} for(int i = 1; i < N; i++){
scanf("%d%d",&v1,&v2);
Graph[v1].push_back(v2);
Graph[v2].push_back(v1);
} for(int i = 1; i <= N; i++){
for(int j = 0; j < Graph[i].size(); j++){
UnionSet(i,Graph[i][j]);
}
} set<int> root;
for(int i = 1; i<= N; i++){
root.insert(FindSet(i));
} if(root.size() != 1){
printf("Error: %d components\n",root.size());
return 0;
} vector<int> maxDeepNodes;
maxDeepNodes.clear();
int maxDepth = 0;
int depth = 0; for(int i = 1; i <= N; i++){
depth = BFS(i);
if(depth > maxDepth){
maxDepth = depth;
maxDeepNodes.clear();
maxDeepNodes.push_back(i);
}else if(depth == maxDepth){
maxDeepNodes.push_back(i);
}
} for(int i = 0; i < maxDeepNodes.size(); i++){
printf("%d\n",maxDeepNodes[i]);
} return 0;
}
1021. Deepest Root (25) -并查集判树 -BFS求深度的更多相关文章
- [PAT] 1021 Deepest Root (25)(25 分)
1021 Deepest Root (25)(25 分)A graph which is connected and acyclic can be considered a tree. The hei ...
- PAT 甲级 1021 Deepest Root (25 分)(bfs求树高,又可能存在part数part>2的情况)
1021 Deepest Root (25 分) A graph which is connected and acyclic can be considered a tree. The heig ...
- 1021. Deepest Root (25)——DFS+并查集
http://pat.zju.edu.cn/contests/pat-a-practise/1021 无环连通图也可以视为一棵树,选定图中任意一点作为根,如果这时候整个树的深度最大,则称其为 deep ...
- PAT甲题题解-1021. Deepest Root (25)-dfs+并查集
dfs求最大层数并查集求连通个数 #include <iostream> #include <cstdio> #include <algorithm> #inclu ...
- 1021. Deepest Root (25)
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...
- PAT (Advanced Level) 1021. Deepest Root (25)
先并查集判断连通性,然后暴力每个点作为根节点判即可. #include<iostream> #include<cstring> #include<cmath> #i ...
- 1021 Deepest Root (25)(25 point(s))
problem A graph which is connected and acyclic can be considered a tree. The height of the tree depe ...
- 1021 Deepest Root (25 分)
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...
- Is It A Tree? POJ - 1308(并查集判树)
Problem Description A tree is a well-known data structure that is either empty (null, void, nothing) ...
随机推荐
- Linux下的crontab定时、执行任务命令详解 oracle 自动备份
在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为&qu ...
- 如何为分布式系统优雅的更换RPC
为啥需要更换RPC? 很多小伙伴都遇到过需要为分布式系统调用更换RPC的问题,为什么会遇到这种事呢?其实,在系统搭建初期,需求简单,架构简单,最重要的是请求量也少,所以很多系统都采用快速原型开发模式, ...
- 美链BEC合约漏洞技术分析
这两天币圈链圈被美链BEC智能合约的漏洞导致代币价值几乎归零的事件刷遍朋友圈.这篇文章就来分析下BEC智能合约的漏洞 漏洞攻击交易 我们先来还原下攻击交易,这个交易可以在这个链接查询到. 我截图给大家 ...
- oracle之子查询、创建用户、创建表、约束
子查询 子查询可以分为单行子查询和多行子查询 单行子查询 [1] 将一个查询的结果作为另外一个查询的条 ...
- 在Spring Boot中使用Spring Security实现权限控制
丢代码地址 https://gitee.com/a247292980/spring-security 再丢pom.xml <properties> <project.build.so ...
- springMVC源码解析--ViewResolver视图解析器执行(三)
之前两篇博客springMVC源码分析--ViewResolver视图解析器(一)和springMVC源码解析--ViewResolverComposite视图解析器集合(二)中我们已经简单介绍了一些 ...
- N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.
N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列.设计加密解密算法,且要求K<=15*N. ...
- Struts 2 之拦截器
拦截器概述 Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP(Aspect Oriented Progr ...
- SQL基本函数
字符型函数 函数名称 描述 LOWER 将特定的字符串转化为小写,只影响字母字符串. UPPER 将整个字符串转换成大写,只影响字母字符串. INITCAP 将字符串中每一个单词的第一个字母转换为大写 ...
- iOS10软件崩溃 Xcode8崩溃 打印/字体等问题汇总 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博!iOS开发者交流QQ群: 446310206 [1].Xcode8代码出现ubsystem: com.apple.U ...