#include <cstdio>
#include <cstdlib>
#include <vector> using namespace std; class Node {
public:
vector<int> adj;
bool visited;
Node() : visited(false) {}
}; void reset_nodes(vector<Node>& nodes) {
int len = nodes.size();
for (int i=; i<len; i++) {
nodes[i].visited = false;
}
} void dfs(int idx, vector<Node>& nodes, int level, int& deepest) {
if (nodes[idx].visited) return;
Node& node = nodes[idx];
node.visited = true;
if (level > deepest) deepest = level; int len = node.adj.size();
for (int i=; i<len; i++) {
dfs(node.adj[i], nodes, level + , deepest);
}
} int find_deepest_from(int idx, vector<Node>& nodes) {
int deepest = ;
// reset visited flag of all the nodes
reset_nodes(nodes); // find the max level from this node(as root)
dfs(idx, nodes, , deepest); int parts = ;
// check if other parts exist
for (int i = nodes.size() - ; i>=; i--) {
if (!nodes[i].visited) {
int dummy = ;
dfs(i, nodes, , dummy);
parts++;
}
} return parts > ? -parts : deepest;
} int main() {
int N = ;
scanf("%d", &N); vector<Node> nodes(N + ); for (int i=; i<N; i++) {
int a, b;
scanf("%d%d", &a, &b);
nodes[a].adj.push_back(b);
nodes[b].adj.push_back(a);
} int res = ;
vector<int> deepnodes;
int deepest = ;
for (int i=; i<=N; i++) {
res = find_deepest_from(i, nodes);
// not connected graph, stop search
if (res < ) {
break;
}
if (res > deepest) {
deepest = res;
deepnodes.clear();
deepnodes.push_back(i);
} else if (res == deepest) {
deepnodes.push_back(i);
}
}
if (res < ) {
printf("Error: %d components\n", -res);
} else {
int len = deepnodes.size();
for (int i=; i<len; i++) {
printf("%d\n", deepnodes[i]);
}
}
return ;
}

最深root的最远leaf也应该是最深root,利用这个做下优化的话速度应该会快不少。下午改写了一发,时间就有原来的1200ms降到了15ms,可见利用问题中的规律还是很有必要的:

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set> using namespace std; class Node {
public:
vector<int> adj;
bool visited;
Node() : visited(false) {}
}; void reset_nodes(vector<Node>& nodes) {
int len = nodes.size();
for (int i=; i<len; i++) {
nodes[i].visited = false;
}
} void dfs(int idx, vector<Node>& nodes, int level, int& deepest, set<int>& leaf) {
if (nodes[idx].visited) return;
Node& node = nodes[idx];
node.visited = true;
if (level > deepest) {
deepest = level;
leaf.clear();
leaf.insert(idx);
} else if (level == deepest) {
leaf.insert(idx);
} int len = node.adj.size();
for (int i=; i<len; i++) {
dfs(node.adj[i], nodes, level + , deepest, leaf);
}
} int find_deepest_from(int idx, vector<Node>& nodes, set<int>& leaf) {
int deepest = ;
// reset visited flag of all the nodes
reset_nodes(nodes); // find the max level from this node(as root)
dfs(idx, nodes, , deepest, leaf); int parts = ;
// check if other parts exist
set<int> dummy_leaf;
int dummy_deepest = ;
for (int i = nodes.size() - ; i>=; i--) {
if (!nodes[i].visited) {
dummy_leaf.clear();
dummy_deepest = ;
dfs(i, nodes, , dummy_deepest, dummy_leaf);
parts++;
}
}
if (parts > ) return -parts; reset_nodes(nodes);
vector<int> root(leaf.begin(), leaf.end());
int len = root.size(); for (int i=; i<len; i++) {
dfs(root[i], nodes, , deepest, leaf);
leaf.insert(root[i]);
} return parts > ? -parts : deepest;
} int main() {
int N = ;
scanf("%d", &N); vector<Node> nodes(N + ); for (int i=; i<N; i++) {
int a, b;
scanf("%d%d", &a, &b);
nodes[a].adj.push_back(b);
nodes[b].adj.push_back(a);
} int res = ;
set<int> deepnodes;
int deepest = ;
res = find_deepest_from(, nodes, deepnodes);
// not connected graph
if (res < ) {
printf("Error: %d components\n", -res);
} else {
auto iter = deepnodes.begin();
while (iter != deepnodes.end()) {
printf("%d\n", *iter++);
}
}
return ;
}

PAT 1021 Deepest Root的更多相关文章

  1. PAT 1021 Deepest Root[并查集、dfs][难]

    1021 Deepest Root (25)(25 分) A graph which is connected and acyclic can be considered a tree. The he ...

  2. [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 ...

  3. PAT甲级1021. Deepest Root

    PAT甲级1021. Deepest Root 题意: 连接和非循环的图可以被认为是一棵树.树的高度取决于所选的根.现在你应该找到导致最高树的根.这样的根称为最深根. 输入规格: 每个输入文件包含一个 ...

  4. PAT 甲级 1021 Deepest Root (并查集,树的遍历)

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

  5. 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 ...

  6. PAT 甲级 1021 Deepest Root

    https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856 A graph which is conne ...

  7. 1021. Deepest Root (25)——DFS+并查集

    http://pat.zju.edu.cn/contests/pat-a-practise/1021 无环连通图也可以视为一棵树,选定图中任意一点作为根,如果这时候整个树的深度最大,则称其为 deep ...

  8. 1021.Deepest Root (并查集+DFS树的深度)

    A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...

  9. 1021. Deepest Root (25) -并查集判树 -BFS求深度

    题目如下: A graph which is connected and acyclic can be considered a tree. The height of the tree depend ...

随机推荐

  1. [I/O]一览图

  2. TX2 自制底板不识别USB

    目的:解决自制的底板无法识别USB,使能3个UART接口,使能3个SPI接口. Jetpack版本:Jetpack-3.1 虚拟机:ubuntu14.04 使用dtb文件夹下的文件替换刷机包../64 ...

  3. Linux 安装python3.7.3 提示已经自动安装了pip和setuptools 可是使用时bash提示没有找到pip

    Linux 安装python3.7.3 提示已经自动安装了pip和setuptools 可是使用时bash提示没有找到pip 今天的任务就是找到解决办法 另外就是用布置好python3的路径

  4. 使用Jenkins进行Android自动打包,自定义版本号等信息【转】

    之前App在提交测试和最终部署的过程中App打包一直是由开发人员来完成的,由于项目比较大, 再加上Android打包本身就比较慢,所以每次打包还是很耗时的.并且按照严格的研发流程来讲,开发人员应该只负 ...

  5. python中的set实现不重复的原理

    最近在尝试写选课系统的时候遇到一个问题: 1.存在两个类 School.Teacher : 2.School实例中包含多个Teacher的实例,但又不可重复 本人想到在School中用set()存储, ...

  6. 接口登录存在动态token

    Jmeter接口登录时获取到的参数token一直在变的问题,导致运行时总是报错 解决方法如下: 1.新建一个GET的HTTP请求 2.添加正则表达式提取器 记得name="_token&qu ...

  7. MarkDown语法实操

    一级标题 这是引用 二级标题 https://daringfireball.net/projects/markdown/dingus 你好啊,这是斜体 引用 添加图片 图片alt就是显示在图片下面的文 ...

  8. python tkinter 基本操作与事件

    基本操作 import tkinter as tk # 引入tk 包 win=tk.Tk() # 引入窗口对象 win.title("窗口标题") # 窗口标题 win.geome ...

  9. yum国内镜像配置

    yum默认链接的还是国外的镜像,速度相对不理想,配置成国内的镜像会快很多,这里以阿里镜像为例进行配置: CentOS系统更换软件安装源 #base源#第一步:备份你的原镜像文件,以免出错后可以恢复.m ...

  10. Codeforces - 38G 可持久化Treap 区间操作

    题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...