A1021 Deepest Root (25分)
一、技术总结
- 这一题题目很好理解,就是求一个图如果只有一个连通块,那么就可以被当做tree,然后要求出所有结点中如果被选中作为根结点,能达到的最大高度,如果有多个按照从小到大的顺序输出。如果有多个连通块,直接输出题目中的要求。
- 但是开始自己写想思路不清晰,也是想就是正常思路,判断深度,然后记录,统计连通分量的数量。最后直接爆炸了。
- 后来知道,可以首先通过一次dfs遍历图一遍,然后统计出当前结点下所有最大深度的叶子结点们,然后再其中任选一个结点,重新遍历一次,统计出一次当前结点下所有最大深度的叶子结点们,然后这连个集合的并集就是答案。这里使用set集合,可以方便的得出答案。这个可以作为结论记下来。这一点是整个题目解题的关键,如果这里没有理解,就会理解不了代码,可以自己画个小图,试一下看结论是否正确。
二、参考代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int n, maxheight = 0;
vector<int> v[maxn];//邻接表
bool visit[maxn] = {false};//判断是否已经访问过
set<int> s;//这是可以自动排序
vector<int> temp;//用于存储具有最大相同高度的结点们
void dfs(int node, int height){
//这一部分是判断当前结点是否是最大高度
if(height > maxheight){
temp.clear();
temp.push_back(node);
maxheight = height;
}else if(height == maxheight){
temp.push_back(node);
}
visit[node] = true;
for(int i = 0; i < v[node].size(); i++){
if(visit[v[node][i]] == false){
dfs(v[node][i], height+1);
}
}
}
int main(){
scanf("%d", &n);
//v.resize(n+1);//
int a, b, cnt = 0, s1 = 0;//cnt记录连通块的数量,s1标记为可以访问到最大高度
for(int i = 0; i < n -1; i++){
scanf("%d %d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
for(int i = 1; i <= n; i++){
if(visit[i] == false){
dfs(i, 1);
if(i == 1){
if(temp.size() != 0) s1 = temp[0];
for(int j = 0; j < temp.size(); j++){
s.insert(temp[j]);
}
}
cnt++;
}
}
if(cnt >= 2){
printf("Error: %d components", cnt);
}else{
temp.clear();
maxheight = 0;
fill(visit, visit+maxn, false);
dfs(s1, 1);
for(int i = 0; i < temp.size(); i++){
s.insert(temp[i]);
}
for(auto it = s.begin(); it != s.end(); it++){
printf("%d\n", *it);
}
}
return 0;
}
作者:睿晞
身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
曾有一个业界大牛说过这样一段话,送给大家:
“华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.