PAT甲级练习1021. Deepest Root (25)
来源:互联网 发布:算法导论22章 编辑:程序博客网 时间:2024/06/05 10:46
1021. Deepest Root (25)
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:51 21 31 42 5Sample Output 1:
345Sample Input 2:
51 31 42 53 4Sample Output 2:
Error: 2 components
#include <iostream>#include <cmath>#include <algorithm>#include <vector>#include <string>using namespace std;int n, x, y, num=0;int maxDepth=0, tmp=0;int r[10001][10001];bool visited[10001];vector<int> lroot;void dfs2(int x, int length){//计算长度visited[x] = true;if(length>tmp){tmp = length;}for(int i=1; i<=n; i++){if(visited[i]==false && r[x][i]==1){dfs2(i,length+1);}}visited[x] = false;}void dfs1(int x){//判断是否只有一个连通域visited[x] = true;for(int i=1; i<=n; i++){if(visited[i]==false && r[x][i]==1){dfs1(i);}}}int main(){scanf("%d", &n);for(int i=1; i<=n-1; i++){scanf("%d %d", &x, &y);r[x][y] = r[y][x] = 1;}for(int i=1; i<=n; i++){if(visited[i]==0){num++;dfs1(i);}}memset(visited, false, 10001);if(num>1){printf("Error: %d components", num);}else{for(int i=1; i<=n; i++){tmp=0;dfs2(i, 0);if(tmp>maxDepth){maxDepth = tmp;vector<int> y;lroot.swap(y);lroot.push_back(i);}else if(tmp==maxDepth){lroot.push_back(i);}}}for(int i=0; i<lroot.size(); i++){printf("%d\n", lroot[i]);}cin>>n;return 0;}
评测结果
测试点
看了一下别人的做法,发现一个有趣的证明:树的直径(最长路)的证明。即从随便一点出发,通过dfs找到最远的节点,再从这一点出发进行dfs即可找到该树中距离最远的点。相关证明可以看看
判断完连通域个数后,可以从任一点开始dfs一遍获得一个最远点的集合,在从该集合中任选一点再dfs一遍即可得到另一组集合,然后合并这两个就是所得的最长的点的集合。注意第二遍不需要对第一遍得到的集合中每一个都去dfs一遍。
#include <iostream>#include <cmath>#include <algorithm>#include <vector>using namespace std;int n, x, y, num=0;int maxDepth=0, tmp=0;int r[10001][10001];bool visited[10001];vector<int> lroot;void dfs2(int x, int length){//计算长度visited[x] = true;if(length>maxDepth){maxDepth = length;vector<int> y;lroot.swap(y);lroot.push_back(x);}else if(length==maxDepth){lroot.push_back(x);}for(int i=1; i<=n; i++){if(visited[i]==false && r[x][i]==1){dfs2(i,length+1);}}//visited[x] = false;}void dfs1(int x){//判断是否只有一个连通域visited[x] = true;for(int i=1; i<=n; i++){if(visited[i]==false && r[x][i]==1){dfs1(i);}}}int main(){scanf("%d", &n);for(int i=1; i<=n-1; i++){scanf("%d %d", &x, &y);r[x][y] = r[y][x] = 1;}for(int i=1; i<=n; i++){if(visited[i]==0){num++;dfs1(i);}}fill(visited, visited+10001, false);if(num>1){printf("Error: %d components", num);}else{visited[1] = true;dfs2(1, 0);vector<int> v1(lroot);//int k=lroot.size();//不需要每个都去dfs一遍//for(int i=0; i<k; i++){//fill(visited, visited+10001, false);//visited[lroot[i]] = true;//dfs2(lroot[i], 0);//}fill(visited, visited+10001, false);dfs2(lroot[0], 0);v1.insert(v1.end(), lroot.begin(), lroot.end());sort(v1.begin(), v1.end());tmp = -1;for(int i=0; i<v1.size(); i++){if(v1[i]!=tmp){printf("%d\n", v1[i]);tmp = v1[i];}}}cin>>n;return 0;}
评测结果
测试点
- PAT甲级练习1021. Deepest Root (25)
- 【PAT甲级】1021. Deepest Root (25)
- 1021. Deepest Root (25) PAT 甲级
- PAT甲级1021. Deepest Root (25)
- PAT 甲级 1021. Deepest Root (25)
- PAT 甲级1021. Deepest Root (25)
- [PAT-甲级]1021.Deepest Root
- PAT 甲级 Deepest Root (25)
- PAT甲级练习题A1021. Deepest Root (25)
- 1021. Deepest Root (25)-PAT
- PAT 1021. Deepest Root (25)
- PAT 1021. Deepest Root (25)
- PAT 1021. Deepest Root (25)
- PAT 1021. Deepest Root (25)
- PAT 1021. Deepest Root (25)
- 【PAT】1021. Deepest Root (25)
- pat 1021. Deepest Root (25)
- 【PAT】1021. Deepest Root (25)
- 事件模式与观察者模式
- Word Ladder II
- 常见的进程调度算法
- 欢迎使用CSDN-markdown编辑器
- 1073. Scientific Notation (20)
- PAT甲级练习1021. Deepest Root (25)
- Canny算子
- Shiro 之认证登录的dem
- PAT-B 1022. D进制的A+B (20)
- Java内存不足之PermGen space错误探究
- 基于Android NDK的交叉编译
- java.lang.OutOfMemoryError: PermGen space及其解决方法
- Activiti工作流简单入门
- NYOJ171 第三届acm省赛 聪明的kk