1021. Deepest Root (25) -并查集判树 -BFS求深度
来源:互联网 发布:数控车床螺纹g92编程 编辑:程序博客网 时间:2024/06/07 07:29
题目如下:
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 calledthe 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:51 21 31 42 5Sample Output 1:
345Sample Input 2:
51 31 42 53 4Sample 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 10002bool 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求深度
- 1021. Deepest Root (25) 并查集+BFS
- pat甲级 1021. Deepest Root(bfs求连通分量)
- [并查集&&BFS]PAT1021 Deepest Root
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- 1021. Deepest Root (25)
- TestNG组测试
- 模板与模板特化
- mysql 自动提交
- WordPress-当文章属于两个或多个分类时,使其在不同的分类使用不同文章模板的方法
- oracle 普通视图 和 物化视图 的区别
- 1021. Deepest Root (25) -并查集判树 -BFS求深度
- 第12周项目1-2
- Mybatis中insert、Update操作返回主键
- NYOJ 10 skiing
- 关于 /sys/class/gpio 简介
- JavaScript中的Function
- 第十三周项目一动物这样叫(3)
- YT02-简单数学课堂题-1004 Fibonacci Again -(5.31日-烟台大学ACM预备队解题报告)
- Java 如何调用操作系统命令