PAT 1021 Deepest Root (25分) 从测试点3超时到满分再到代码优化

PAT甲级真题 1021 Deepest Root (25分) C++实现(两次DFS遍历,注意测试点3内存超限错误,需用邻接表存储图) 题目 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 r... 阅读详情

题目

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 (≤104​​ ) 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条边,问其能否形成一棵树,如果不可以,请输出
“Error: %d components”,其中这个%d指的是这个图的连通分量个数;如果可以形成树,那请问,哪个节点作为树根,这棵树将会有最大的高度?如果多个节点都能达到这个要求,将这些节点按顺序输出。

关于图的连通分量,一般都会采用并查集或者DFS来进行判断,我们这里选择用DFS,因为这个思路真的简单

思路一(测试点3超时)

  1. dfs(i) 判断连通分量的个数:
    用一个visit数组记录节点的访问状况,初始化为false,dfs内把和i直接关联或间接关联的节点都标记为true,这样,就相当于一个连通分量从整个节点集中排除出去了,我们需要统计dfs执行了多少次才使得visit数组全为false,就能得到连通分量的个数。
  2. 让每个节点都作为根节点,利用dfs(i, deep, deepest)函数去求得这棵树的最大深度,并用一个全局的maxheight记录全局最优,如果它更大(deepest>maxheight),那就把之前保存的根的集合roots清空,把它加进去;如果它作为根得到的deepest==maxnheight,那就把它直接加入roots。
  3. 看看代码吧,注释已经不能再详细了。
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// n个节点
int n;
// 邻接矩阵,下标从1开始,最终造成内存溢出,测试点3结果是超时,内存占用显示0
bool edge[10001][10001];
// 能使得高度最大的全部节点
vector<int> maxheight_roots;
// 最大高度
int maxheight;

bool visit[10001];
// 用于 深度优先搜索判断它有几个连通分量,
// 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
// 判断 执行了几次 dfs才使得visit全为true,就知道有几个连通分量,如果连通分量大于1,那么就不是一棵树
void dfs(int s) {

    visit[s] = true;
    for (int j = 1; j <= n; ++j) {
        // 和他直接或间接相连的点全标为true
        if (edge[s][j] && !visit[j])
            dfs(j);
    }
}
// 用于求得 以每个节点作为根节点,能得到的最大高度
// deepest保存这个结果,注意这个引用传值,相当于c语言中的指针,能改变这个值
// deep 当前节点s在第几层
// 其实上面那个函数没必要创建,用这个就可以了,只是为了让大家看清楚我的思路
void dfs(int s, int deep, int &deepest) {
    // 更新 最大高度
    if (deep > deepest) {
        deepest = deep;
    }

    visit[s] = true;

    for (int j = 1; j <= n; ++j) {
        // 和它直接相连的,相当于全是它的孩子,全在它的下一层
        if (edge[s][j] && !visit[j]) {
            dfs(j, deep + 1, deepest);
        }
    }
}

int main() {

    cin >> n;

    int f, t;
    // n个节点n-1条边
    for (int i = 1; i < n; ++i) {
        cin >> f >> t;
        // 构建邻接矩阵
        edge[f][t] = edge[t][f] = true;
    }
    // 统计连通分量的个数
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
        if (!visit[i]) {
            // 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
            dfs(i);
            cnt++;
        }
    }
    // 超过一个连通分量,不能构成树
    if (cnt > 1) {
        printf("Error: %d components", cnt);
        return 0;
    }
    // 以每个节点为根节点,得到它形成的树的最大高度
    for (int i = 1; i <= n; ++i) {
        fill(visit, visit + n + 1, false);
        // 保存以i为根的树的最大高度
        int deepest = 0;
        // 根节点是第一层,因为是引用传值,执行完后deepest改变
        dfs(i, 1, deepest);
        // 如果这棵树的最大高度大于全局保存的最大高度
        if (deepest > maxheight) {
            // 更新最大高度
            maxheight = deepest;
            maxheight_roots.clear();
            // 只把它做为根节点
            maxheight_roots.push_back(i);
        // 这棵树的最大高度和全局最大高度相等,说明它也是一个符合要求的根节点
        } else if (deepest == maxheight) {
            // 加进来
            maxheight_roots.push_back(i);
        }
    }
    // 输出所有合法的根节点即可
    for (auto it : maxheight_roots)
        cout << it << endl;

    return 0;
}

最终结果是 测试点3超时了
在这里插入图片描述
可以很明显看出来是内存溢出!!!!(内存显示的是0啊),为啥呢?树 是稀疏图,用邻接矩阵去存太浪费空间了。

思路二(满分通过,但运行时间太长)

既然知道问题在哪,那么就好办了,我们只需要把邻接矩阵改为邻接表进行存储就好了,我们用可变数组vector。

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

// n个节点
int n;
// // 邻接矩阵,下标从1开始
// bool graph[10001][10001];
// 邻接表,改成邻接表后测试点3通过,但是运行时间1131ms
vector<vector<int>> graph;
// 
vector<bool> visit;

// 能使得高度最大的全部节点
vector<int> maxheight_roots;
// 最大高度
int maxheight;


// 用于求得 以每个节点作为根节点,能得到的最大高度
// deepest保存这个结果,注意这个引用传值,相当于c语言中的指针,能改变这个值
// deep 当前节点s在第几层
// 其实上面那个函数没必要创建,用这个就可以了,只是为了让大家看清楚我的思路
void dfs(int i, int deep, int &deepest) {
    // 更新 最大高度
    if (deep > deepest) {
        deepest = deep;
    }
    // 如果忽略上面那几行代码和后两个参数,就是用来 深度优先搜索判断它有几个连通分量,
    // 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
    // 判断 执行了几次
    // dfs才使得visit全为true,就知道有几个连通分量,如果连通分量大于1,那么就不是一棵树

    visit[i] = true;

    for (int j = 0; j < graph[i].size(); ++j) {
        // 和它直接相连的,相当于全是它的孩子,全在它的下一层
        // 注意换成邻接表后的写法
        if (!visit[graph[i][j]]) {
            dfs(graph[i][j], deep + 1, deepest);
        }
    }
}

int main() {

    cin >> n;

    graph.resize(n + 1);
    visit.resize(n + 1);

    int f, t;
    // n个节点n-1条边
    for (int i = 1; i < n; ++i) {
        cin >> f >> t;
        // 构建邻接表
        graph[f].push_back(t);
        graph[t].push_back(f);
    }
    // 统计连通分量的个数
    int cnt = 0, any = 0;
    for (int i = 1; i <= n; ++i) {
        if (!visit[i]) {
            // 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
            dfs(i, 0, any);
            cnt++;
        }
    }
    // 超过一个连通分量,不能构成树
    if (cnt > 1) {
        printf("Error: %d components", cnt);
        return 0;
    }
    // 以每个节点为根节点,得到它形成的树的最大高度
    for (int i = 1; i <= n; ++i) {
        fill(visit.begin(), visit.end(), false);
        // 保存以i为根的树的最大高度
        int deepest = 0;
        // 根节点是第一层,因为是引用传值,执行完后deepest改变
        dfs(i, 1, deepest);
        // 如果这棵树的最大高度大于全局保存的最大高度
        if (deepest > maxheight) {
            // 更新最大高度
            maxheight = deepest;
            maxheight_roots.clear();
            // 只把它做为根节点
            maxheight_roots.push_back(i);
            // 这棵树的最大高度和全局最大高度相等,说明它也是一个符合要求的根节点
        } else if (deepest == maxheight) {
            // 加进来
            maxheight_roots.push_back(i);
        }
    }
    // 输出所有合法的根节点即可
    for (auto it : maxheight_roots)
        cout << it << endl;

    return 0;
}

看看结果吧
在这里插入图片描述
1310ms,扎心了老铁,why??? why??? 不能怪我没有优化,因为我不会!!!

最终版本

不参考各路大神的代码,我怎么可能会优化呢?天真!!,果然,各路大神都是这么干的,果然不是我能想到的:

  1. 从任意一个节点开始进行深度优先遍历,找到离他最远的所有节点(可能不止一个,记为集合A);
  2. 再从A中任意选一个节点出发进行深度优先遍历,找到离他最远的节点(记为集合B),
  3. 最后最深根就是这两个集合的并集。

为啥呢??其实我自己拿纸画了画,大概是能明白的,但我可能说不清楚,所以我在这里把牛客网的链接贴出来大家自己去看看,说的挺清楚的。(牛客网解释)

不过为了防止链接以后失效了,我在这里把最好的两个解释直接贴出来吧。

解释一:

这个算法有一个很玄奥的地方,就是两次遍历都有帅气逼人地用到了任取一词,为了说明算法的正确性,让我先上一张图
在这里插入图片描述
就是上面这幅图,圆的是顶点,长的是边,中间蓝色加省略号是省略省略不提的部分,然后红色是主干,也就是最长路,绿色是侧枝。

很容易理解对于任何一条侧枝 DE,存在|DE| < min(|AD|,|DC|),现在分类讨论:

  1. 对于第一次DFS选择的起点,如果是红色路径上的点,第一次DFS得到的最长路必定是距离较远的最长路顶点,在这幅图中就是说要么是A,要么是C,同时可以看到,假如起点是B,我们在DFS的时候E点的DFS深度也会是最长路径,也就是说我们选出了最起码一侧的所有最长路的端点。
  2. 如果第一次选择的起点是侧枝上的点,如F (侧枝上还有侧枝的情况请自行脑补) ,F在进行DFS搜索的时候必定会经过D点,那么问题已经转化成了第一题的问题。
    至于第二次DFS应该很好理解既然第一次选出了一端的所有顶点,第二次肯定会选出另一端所有顶点。

    至此该问题圆满解决。

解释二:

从任意一个节点开始进行深度优先遍历,找到离他最远的节点(可能不止一个,记为集合A);第二步:再从A中任意选一个节点出发进行深度优先遍历,找到离他最远的节点(记为集合B),最后最深根就是这两个集合的并集。

证明:第一步找出的节点一定是全局的最深根。

1 根据全局最优解一定是局部最优解的原理:最后全局的最深根一定也是某个局部最优解,比如:因为全局最深的根是固定的,不失一般性,我们就把他们标为1、2、3、4、5,那么从图中中任意一点出发,例如A,从他出发找到的局部最优解一定是在1、2、3、4、5,反之,如不在,也就是说有比1、2、3、4、5更深的节点,我们假设它存在并且成为B,那么可想而知,从1到B肯定要比从1到2要深,这就与1、2、3、4、5是全局最优解矛盾,所以假设不成立。原命题成立。即局部最优解一定在1、2、3、4、5中。

2 由第一步知道局部最优解是固定的,且全局最优解是局部最优解,根据这两条结论,得出:第一次遍历得到的最深的节点就是最深根

由于从最深根出发到最深的叶子节点是相互对称的,所以我们再从当前的最深根出发遍历一次得到其他的最深根,然后做一次去重即可。

下面贴上我自己的写的代码吧,参考了柳神的代码,然后自己省去了一些小瑕疵,注释还是日常详细详细再详细,给你最好的阅读体验,哈哈哈。

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

/**
 * 牛客网解释:https://www.nowcoder.com/questionTerminal/f793ad2e0c7344efa8b6c18d10d4b67b
 * 1.
 * 从任意一个节点开始进行深度优先遍历,找到离他最远的节点(可能不止一个,记为集合A);
 * 2.
 * 再从A中任意选一个节点出发进行深度优先遍历,找到离他最远的节点(记为集合B),
 * 3. 最后最深根就是这两个集合的并集。
 */

// n个节点
int n;

// 邻接表,下标全从0开始,
vector<vector<int>> graph;
// 下标从0开始
vector<bool> visit;

// 保存dfs时,得到的最深层节点
vector<int> temp_roots;

// 最大高度
int maxheight;

// 用于求得 以每个节点作为根节点,能得到的最大高度
// deepest保存这个结果,注意这个引用传值,相当于c语言中的指针,能改变这个值
// deep 当前节点s在第几层
// 其实上面那个函数没必要创建,用这个就可以了,只是为了让大家看清楚我的思路
void dfs(int i, int deep) {
    // 更新 最大高度
    if (deep > maxheight) {
        // 更新最大高度
        maxheight = deep;
        temp_roots.clear();
        // 只把它做为根节点
        temp_roots.push_back(i);
        // 这棵树的最大高度和全局最大高度相等,说明它也是一个符合要求的根节点
    } else if (deep == maxheight) {
        // 加进来
        temp_roots.push_back(i);
    }
    // 如果忽略上面那几行代码和后两个参数,就是用来
    // 深度优先搜索判断它有几个连通分量,
    // 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
    // 判断 执行了几次
    // dfs才使得visit全为true,就知道有几个连通分量,如果连通分量大于1,那么就不是一棵树

    visit[i] = true;

    for (int j = 0; j < graph[i].size(); ++j) {
        // 和它直接相连的,相当于全是它的孩子,全在它的下一层
        // 注意换成邻接表后的写法
        if (!visit[graph[i][j]]) {
            dfs(graph[i][j], deep + 1);
        }
    }
}

int main() {

    cin >> n;

    graph.resize(n + 1);
    visit.resize(n + 1);

    int f, t;
    // n个节点n-1条边
    for (int i = 1; i < n; ++i) {
        cin >> f >> t;
        // 构建邻接表
        graph[f].push_back(t);
        graph[t].push_back(f);
    }
    // 统计连通分量的个数
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
        if (!visit[i]) {
            // 每进行一次dfs,就划分出一个连通分量,visit集合中这部分节点都变成true
            dfs(i, 1);
            cnt++;
        }
    }
    // 超过一个连通分量,不能构成树
    if (cnt > 1) {
        printf("Error: %d components", cnt);
        return 0;
    }
    // 从第一次dfs得到的集合temp_roots拿出一个根,再进行一次dfs,得到集合B
    // 集合取交集就是结果,多个根的话,还要按大小火顺序保存,我们借助一个set
    set<int> roots;
    // 先把集合A转移进来,
    for (auto it : temp_roots)
        roots.insert(it);
    // 清空temp_roots以保存集合B
    temp_roots.clear();
    // 清空visit
    fill(visit.begin(), visit.end(), false);
    // 再以集合A中任意一个元素作为根去dfs
    dfs(*roots.begin(), 1);
    // 再把集合B转移进来,相当于取了并集,set自动去重排序
    for (auto it : temp_roots)
        roots.insert(it);
    
    // 输出所有合法的根节点即可
    for (auto it : roots)
        cout << it << endl;

    return 0;
}

再看看结果
在这里插入图片描述
这下子就满意多了,^_^

1021 Deepest Root (测试点4、5报错的解决办法) (代码来自柳婼https://github.com/liuchuo/PAT/blob/master/AdvancedLevel_C%2B%2B/1021.%20Deepest%20Root%20(25)%20.cpp) 步骤: ①先以节点1为根节点进行DFS,找出最长的几个路径的终点temp[ ]并输入到set中,同时记录连通分量个数cnt (这里必须把终点全部输入到set中,如果只输入temp[... 阅读详情

相关推荐

fdtd(时域有限差分)仿真

基础入门阶段采用 Step by step 的教学方式带着做具体的案例,在案例中学习 FDTD 应用的。的痛难点,将 FDTD 仿真引入实验当中,通过软件可视化处理有效直观的展示仿真的流程,与实验数。图像传感器,OLED 和液晶,表面计量,表面等离子体,石墨烯,太阳能电池,集成光子组件,超材。料,衍射光学和光子晶体。波,场极化,磁场,周期性结构,半球功率积分等设计解决方案,提供时域有限差分分析函数,时域。子光学传感器、热电子光探测器的光学特性研究、光学微腔宽带吸收器等多个方向的研究方法。

y2715163545的博客 5445

PAT A1129(测试点3,4运行超时,有助于扩展对STL的高级应用)

一看到这题,简单,一个map记录访问次数,再把map转化为vector排序就能解决,结果。。运行超时。。。关键是还不知道怎么解决,还来才想起是 sort() 的问题 代码如下: 参考博客:链接 unordered_map+数组+排序,排序每次复杂度nlog n,每插入一个元素,排序一次,复杂度n^2log n,远没有用map,set排序快,用set复杂度nlog n; #include<iostream> #include<unordered_map> #include<a.

学习笔记,不喜勿喷! 116

手把手教你用C语言实现GNSS卫星方位角计算(附RTKLIB风格代码解析)

本文详细介绍了如何使用C语言实现GNSS卫星方位角计算,包括从地固坐标系到站心坐标系的转换链条。通过RTKLIB风格的代码解析,展示了XYZ到ENU坐标转换的核心原理和C语言实现框架,帮助开发者掌握卫星方位角和高度角的计算技巧,适用于GNSS观测数据质量分析和精密定位算法开发。

weixin_30699915的博客 365

1025 PAT Ranking (25分)java实现,最后一个测试点超时

处理排名(1 1 3 4 4 6)的方式有两种 第一种方法:第一个人记为1,遍历剩余个体 bl.get(0).rank=1; for(int k=1;k<bl.size();k++) { if(bl.get(k).score==bl.get(k-1).score) { bl.get(k).rank=bl.get(k-1).rank; }else { bl.get(k).rank=...

anzhilanxiao的博客 523

单波束与多波束声呐:从原理到应用场景的全面解析

本文全面解析了单波束与多波束声呐的工作原理、核心特点及应用场景。单波束声呐如精准的狙击手,适合高精度需求;多波束声呐则像高效的散弹枪,适用于快速测绘和大面积覆盖。文章还提供了选型指南和前沿发展趋势,帮助用户根据预算和需求选择最适合的声呐技术。

weixin_30872157的博客 220

IMU标定中的Allen方差

Allen方差 Allen方差是IMU标定任务中的常用工具。IMU标定可以分为确定性误差和随机误差,确定性误差包括:scale、bias、misalignment。随机误差则主要是高斯白噪声和bias随机游走。Allen方差主要用于标定随机误差。 Allen方差获取 Allen方差的计算方法如下: 保持IMU静止, 采集N个数据点。 将N个点定长分组,常用的交叠式Allen方差如下(n=3): 对于每个子集,计算均值后,计算相邻两组的方差,得到的时间-方差曲线即为Allen方差。 Alle

realjc的博客 5734

PAT_1021 Deepest Root (25 分) (记录段错误和超时的解决)

题目链接 首先跑一遍DFS获取连通分支数,当只有一个连通分支时,再搜索能让树最深的根节点(主要参考《算法笔记》的做法)。 记录一下错误: 段错误:基本上段错误都是因为数组越界导致的,要么是数组开的不够大,要么访问了数组外的地址,本题中告诉N个结点,接下来N-1行是边的信息,如果for循环写顺手很容易写成i=0;i<N;i++,应该是i=0;i<N-1;i++,当然这还是审题不清的锅。 按照《算法笔记》讲的思想,首先从任意节点出发dfs得到一个最深的叶结点集合A,然后从A集合中任意选一个结点

Kerin的博客 361

SoC 内的 CPU、GPU、DSP、NPU 协同执行结构图解析:多异构协同的最新实战体系

随着移动端 AI 能力迅速演进,SoC(System on Chip)内部的多种异构计算单元(CPU、GPU、DSP、NPU)之间的协同执行能力成为衡量芯片智能算力的关键指标。本文基于截至 2025 年 5 月最新主流国产芯片(如海思昇腾、地平线旭日、联发科天玑、高通骁龙 8 Gen 系、寒武纪思元等)在实际落地应用中的公开结构与技术资料,深入解析 CPU-GPU-DSP-NPU 协同执行的体系结构、执行路径与调度逻辑。文章结合 Android NNAPI、Vulkan Compute、自定义调度器等工程实

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 8710

1021 Deepest Root (25 分)连通图个数、图的遍历dfs

①测试点3超时,我没有考虑有环的情况,拓扑排序好像是可以判断有向无环图吧,应该是for dfs用太多啦 ②memset的头文件是string.h,fill是algorithm ③并查集可以找两个集合的共同元素,也可以合并,但是求连通图个数,如果需要dfs,用这个最简单 for(int i=1;i<=n;i++){ if(vis[i]==false){ dfs(i,1); block++; } } #includ

qq_42835526的博客 222

2025华为杯第二十二届中国研究生数学建模竞赛D题:低空湍流监测及最优航路规划 - 完整解题分析+完整MATLAB源码!(上篇)

🎓 本文收录于 《滚雪球学数学建模》专栏,本专栏专注于从零基础出发,带你循序渐进掌握数学建模的核心方法与思维路径。通过“滚雪球式”学习法,从最简单的生活化案例到经典建模工具,再到省赛、国赛真题实战演练,逐步积累知识与技能,帮助你搭建完整的建模体系。无论你是刚接触建模的新生,还是希望提升科研与竞赛能力的学者与工程师,本专栏都将为你提供一条清晰、高效、可实操的建模成长路线,助力你快速进阶,突破难点,迈向数学建模竞赛与实际应用的更高峰 🚀!

**My Coding Family** 2587

【StarRocks】-- DATETIME 与 TIMESTAMP 区别详解

本文详细解析了StarRocks中DATETIME/DATETIMEV2与TIMESTAMP的区别及使用场景。DATETIME系列存储人类可读时间,不携带时区;TIMESTAMP实际指Unix时间戳,建议用BIGINT存储。关键差异包括:精度选择(DATETIMEV2支持微秒级)、时区处理(仅函数计算时影响)、存储方式等。针对不同场景提供选型建议:单时区展示用DATETIMEV2,跨时区计算用BIGINT存储Epoch。特别强调与MySQL迁移时的注意事项,并给出常见问题解决方案和最佳实践清单,包括统一入口

欢迎来到我的博客,一起探索代码里的世界! 500

【PAT】1021 个位数统计

【PAT】1021 个位数统计

m0_52031708的博客 433

【华为OD机试真题】4、字符统计及重排 | 机试真题+思路参考+代码解析(C++、Java、Py)

题目描述 >给出一个仅包含字母的字符串,不包含空格,统计字符串中各个字母(区分大小写)出现的次数, 并按照字母出现次数从大到小的顺序。输出各个字母及其出现次数。 如果次数相同,按照自然顺序进行排序,且小写字母在大写字母之前

KJ.JK 3289

1021 Deepest Root (25 分) 测试点1是n=1 惊不惊喜

1021Deepest 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 ...

qq_32691667的博客 782

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

1021 Deepest Root (25)(25 分)

1021 Deepest Root (25)(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 i...

CODER的博客 2340

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

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 calledthe deepest root. Input Specification: Each .

muAluo的博客 442

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

1021 Deepest Root (25 分)(树的遍历)

1021 Deepest Root (25 分)(树的遍历) A graph which is connected and acyclic can be considered a tree. The hight of the tree depends on the selected root. Now you are supposed to find the root that results i...

virgilshi的博客 581

PAT_甲级_1021 Deepest Root (25分) (C++)【DFS/连通分量/段错误/超时 #简单清晰!】

1,题目描述 题目大意 一棵树以不同的节点作为根节点时,树可能会有不同的高度,使树的高度达到最大值时的节点为Deepest Root。 输入 第一行:节点数目N(<=10^4,编号1-N) N-1行:描述树中每条边连接的两个节点 2,思路 3,代码 ...

&再见萤火虫&的博客 548

1021 Deepest Root (25 分)

DFS 似乎找到了PAT的一些规律,如果考的是数据结构里面的东西,就很少有坑。 而如果考的模拟或者简单的题,就有很多边界条件。 使用了两个全局变量,记录每个起点遍历的最大深度和所有顶点的最大深度。 一次性AC,还是比较开心的! #include&lt;cstdio&gt; #include&lt;vector&gt; #include&lt;cstring&gt; using namespace ...

姚军 614

1021 Deepest Root (25)(25 分)(C++)

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

qq_41562704的博客 516

PAT A1021

题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856 测试1段错误:没有考虑到n=1的情况 测试3运行超时:我的思路是把每个节点的最大深度找到,然后排序。算法太挫,最后只有23分,没办法了。 #include <cstdio> #include <cstring&g...

我好像在哪儿见过你 309

(自用随笔)PAT A1021(25分)

暴力搜索,测试点3用了1200ms。。。。尴尬。 测试点2比较坑,连通分支数大于2,而我一开始的代码是,一旦连通分支大于1则跳出。。。 暴力思路:先把节点1作为根,用一次图的遍历模板,将连通分支数算出来,若大于1则输出Error;若等于1,则把剩下的节点分别作为根,遍历,算出各自的最大深度,最后输出最大深度的节点。 优化的思路请参考其他博客~ #include <iostream&...

Freedomer_的博客 276

PAT 1021 Deepest Root (25 分)(最后两个测试点错误)燚

A graph which is connected and acyclic can be considered a tree. The hight 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 i...

永无止境 2271

PAT甲级1021题,部分测试点无法通过

#include &lt;cstdio&gt; #include &lt;vector&gt; #include &lt;algorithm&gt; namespace PATA1021{     using namespace std;     const int MAXN=10001;     int n,maxH=0;     int father[MAXN];     bool is...

baosheyun0847的博客 2899

B1021 Deepest Root (强连通+DFS)

B1021 Deepest Root (25分) //哇,这题炸的好惨~~ 1.题目理解问题,不用考虑是否会有个环,保证了它是个强连通图,且是棵树。 2.看到要算几个连通图,直接打完并查集,打完后发现,还是要dfs遍历一遍,没理解并查集的本质是啥??? 3.并查集打完磕磕绊绊21分,两个点测试点1和测试点3(写在下面了)。 第一次递归找左侧最长,...

没有期待的日子反而会顺顺利利 211
上一篇: PAT 1020 Tree Traversals (25分)思路分析 + 满分代码
下一篇: PAT 1013 Battle Over Cities (25分) 图的连通分量+DFS
wwang_dev
博客等级 码龄7年 27粉丝 76原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值