#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. 前端CSS的基本素养

    前端开发的三驾马车——html.css.js,先谈谈CSS CSS 前期:解决布局.特效.兼容问题 中级:网站风格的制定.色调.模块.布局方式.交互方式.逻辑设计等 高级:模块命名.类的命名.文件的组 ...

  2. 字符串变dict

    1.eval 2.json # NameError: name # 'null' is not defined # i_dict=eval(i) 这种方式,如果dict字符串中有null ,将不能变成 ...

  3. LeetCode934.shortest bridge【dfs+bfs】

    一.题面 在给定的二维二进制数组 A 中,存在两座岛.(岛是由四面相连的 1 形成的一个最大组.) 现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛. 返回必须翻转的 0 的最小数目.( ...

  4. 本地安全策略命令行secedit设置本地账户安全策略

    我们日常运行的控制台程序secpol.msc里面的内容,实质可以通过命令行完成,下面演示通过secedit命令来设置本地账号密码策略,启用密码复杂性和强制长度至少8位操作办法. ==> 新建文本 ...

  5. [转] Spring Boot配置多个DataSource

    [From]  https://www.liaoxuefeng.com/article/001484212576147b1f07dc0ab9147a1a97662a0bd270c20000 Sprin ...

  6. Oracle SET UNUSED的用法

    SET UNUSED的用法 原理:清楚掉字典信息(撤消存储空间),不可恢复.    可以使用 SET UNUSED选项标记一列或者多列不可用.    使用DROP SET UNUSED选项删除被被标记 ...

  7. 神马是代码简单的cmd模式,这就是!

    小狼正在研究 “怎么查找连在一起的同色方块?”算法问题 ,突然感觉我是不是需要一种开发模式,不然感觉自己的代码好乱的. 可能是研究算法吧,导致小狼的思路特别清晰,加上也用了差不多1年的nodejs.s ...

  8. 【研究】CVE-2015-1635-HTTP.SYS远程执行代码漏洞(ms15-034)

    1.1.1  漏洞描述 在2015年4月安全补丁日,微软发布的众多安全更新中,修复了HTTP.sys中一处允许远程执行代码漏洞,编号为:CVE-2015-1635(MS15-034 ).利用HTTP. ...

  9. 坐标&接龙型动态规划 - 20181026

    109. Triangle 此题还可以用DFS,记忆化搜索去做,二刷实现 public class Solution { /** * @param triangle: a list of lists ...

  10. PIE SDK波段运算

    1.算法功能简介 波段运算(Band Math)工具能够方便的执行图像中的各个波段的加减乘除.三角函数.指数.对数等数学函数计算,也可以使用IDL编写的函数. 由于每个用户都有独特的需求,利用此工具用 ...