【题目大意】

给出n个结点和n-1条边,问它们能否形成一棵n个结点的树,如果能,从中选出结点作为树根,使整棵树的高度最大。输出所有满足要求的可以作为树根的结点。

【思路】

方法一:模拟。

1 连通、边数为n-1的图一定是一棵树。因此先判断连通图个数(用DFS遍历图,从而计算连通图个数),等于1则能形成一棵树。

2 遍历每一个节点,假设它为根节点构造一棵树。

方法二:

1 由于连通、边数为n-1的图一定是一棵树,因此需要判断给定数据是否能使图连通。
2 确定图连通后,则确定了树,选择合适根结点使树高最大的做法为:
先任意选择一个结点,从该节点开始遍历整棵树,获取能达到的最深的结点,记为集合A;然后从集合A中任意一个结点出发遍历整棵树,获取能达到的最深顶点,记为结点集合B。集合A与B的并集就是所求结果。

https://blog.csdn.net/hy971216/article/details/82252707

https://blog.csdn.net/qq_38677814/article/details/80859998

https://blog.csdn.net/sinat_29278271/article/details/47934611

【tips】

1 非二叉树其实可以想象成一个特殊的图来解决。像这一题,用的其实全都是图的知识来解决,因为其考点不在父子关系上。

2 也可以使用并查集判断连通图个数(未实践过):每读入一条边的两个端点,判断这两个端点是否属于相同的集合,如果不同,则将它们合并到一个集合中,当处理完所有边后根据最终产生的集合个数是否为1来判断给定的图是否连通。

【AC代码】

方法一:

 #include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define N 10002
vector<int>G[N];
int n;
int vis[N] = { false };
int level[N] = { };
void DFS(int u)
{
for (int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
if (vis[v] == false)
{
vis[v] = true;
DFS(v);
}
}
}
int BFS(int root)
{
int mlevel = ;
queue<int>q;
q.push(root);
vis[root] = true;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
if (vis[v] == false)
{
q.push(v);
vis[v] = true;
level[v] = level[u] + ;
if (level[v] > mlevel)
mlevel = level[v];
}
}
}
return mlevel;
}
int main()
{
cin >> n;
int i;
for (i = ; i < n - ; i++)
{
int t1, t2;
cin >> t1 >> t2;
G[t1].push_back(t2);
G[t2].push_back(t1);
}
int tu = ;
for (i = ; i <= n; i++)
{
if (vis[i] == false)
{
tu++;
vis[i] == true;
DFS(i);
}
}
if (tu > )
{
cout << "Error: " << tu << " components";
return ;
}
int maxLevel = ;
vector<int>ans;
for (i = ; i <= n; i++)
{
fill(vis, vis + N, false);
fill(level, level + N, false);
int ceng = BFS(i);
if (ceng == maxLevel)
{
ans.push_back(i);
}
if (ceng > maxLevel)
{
ans.clear();
ans.push_back(i);
maxLevel = ceng;
}
}
for (i = ; i < ans.size(); i++)
cout << ans[i] << endl; return ;
}

方法二:

 #include<iostream>
#include<queue>
#include<vector>
#include<set>
using namespace std;
#define N 10002
vector<int>G[N];
int n;
bool vis[N] = { false };
int level[N] = { };
void DFS(int u)
{
for (int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
if (vis[v] == false)
{
vis[v] = true;
DFS(v);
}
}
}
int BFS(int root)
{
int mlevel = ;
queue<int>q;
q.push(root);
vis[root] = true;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
if (vis[v] == false)
{
q.push(v);
vis[v] = true;
level[v] = level[u] + ;
if (level[v] > mlevel)
mlevel = level[v];
}
}
}
return mlevel;
}
int main()
{
cin >> n;
int i;
for (i = ; i < n - ; i++)
{
int t1, t2;
cin >> t1 >> t2;
G[t1].push_back(t2);
G[t2].push_back(t1);
}
int tu = ;
for (i = ; i <= n; i++)
{
if (vis[i] == false)
{
tu++;
vis[i] = true;
DFS(i);
}
}
if (tu > )
{
cout << "Error: " << tu << " components";
return ;
} fill(vis, vis + N, false);
fill(level, level + N, );
int maxlevel = BFS();
set<int>ans;
for (i = ; i <= n; i++)
if (level[i] == maxlevel)
ans.insert(i);
set<int>::iterator it = ans.begin();
int v = *it;
fill(vis, vis + N, false);
fill(level, level + N, );
maxlevel = BFS(v);
for (i = ; i <= n; i++)
if (level[i] == maxlevel)
ans.insert(i);
for (it = ans.begin(); it != ans.end(); it++)
cout << *it << endl; return ;
}

[PAT] A1021 Deepest Root的更多相关文章

  1. PAT A1021 Deepest Root (25 分)——图的BFS,DFS

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

  2. PAT甲级——A1021 Deepest Root

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

  3. PAT Advanced A1021 Deepest Root (25) [图的遍历,DFS,计算连通分量的个数,BFS,并查集]

    题目 A graph which is connected and acyclic can be considered a tree. The height of the tree depends o ...

  4. A1021. Deepest Root

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

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

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

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

  7. PAT 1021 Deepest Root

    #include <cstdio> #include <cstdlib> #include <vector> using namespace std; class ...

  8. PAT_A1021#Deepest Root

    Source: PAT A1021 Deepest Root (25 分) Description: A graph which is connected and acyclic can be con ...

  9. PAT甲级1021. Deepest Root

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

随机推荐

  1. Go语言实现:【剑指offer】二叉搜索树与双向链表

    该题目来源于牛客网<剑指offer>专题. 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. Go语言实现: type T ...

  2. php面试笔记(3)-php基础知识-运算符

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ...

  3. 编写windows服务程序

    2012-11-02 08:54 (分类:计算机程序) windows服务是一个运行在后台并实现勿需用户交互的任务的控制台程序,对于隐藏程序有很大帮助. 用了几天时间概括了编写windows服务程序的 ...

  4. ubuntu python及python IDLE 的安装

    ubuntu下Python的安装和使用 文章参考出处:https://www.cnblogs.com/luckyalan/p/6703590.html ubuntu14.04 安装Python2.7: ...

  5. vue路由+vue-cli实现tab切换

    第一步:搭建环境 安装vue-cli cnpm install -g vue-cli安装vue-router cnpm install -g vue-router使用vue-cli初始化项目 vue ...

  6. 学Python必背的初级单词,你都背了吗?

    今天给大家分享一些学习Python必须认识的英文单词,同时也是学习编程都必须会的单词,新手赶快学起来!有点长耐心看完. 小编推荐一个学Python的学习裙:九三七六六七 五零九,无论你是大牛还是小白, ...

  7. 11种常用css样式之开篇文本字体学习

    常见css样式:1.字体与颜色2.背景属性3.文本属性4.边框属性5.鼠标光标属性6.列表样式7.定位属性8.内外边距9.浮动和清除浮动10.滚动条11.显示和隐藏 文本:1.letter-spaci ...

  8. 来简单说说var,let,const,function,import,class

    一.var和let var已经在JavaScript中存在很长一段时间了,但是它存在了一些不足的地方,接下来我们就来看看吧 首先var存在变量提升,这是怎么一回事呢,我们看下面代码 为什么是它呢,是因 ...

  9. 避免XSS攻击

    遭遇XSS攻击怎么解决 XSS的攻击手段 利用JavaScript或DOM方式进行攻击,XSS(脚本注入)提交,然后进行页面展示,影响页面的正常结构,还可以做钓鱼网站,来盗取用户的信息. 比如在页面评 ...

  10. Lucene之分析器

    什么是分析器? 分析(Analysis)在Lucene中指的是将域(Field)文本转换为最基本的索引表示单元—项(Term)的过程. 分析器(Analyzer)对分析操作进行了封装,通过执行一系列操 ...