【题目大意】

给出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. NR / 5G - Uplink Carrier Waveform Generation

  2. JavaScript 构造函数的继承

    JavaScript 构造函数的继承 在上一篇文章中讲述了 JS 对象.构造函数以及原型模式,这篇文章来讨论下 JavaScript 的继承 继承是 OO 语言中的一个最为人津津乐道的概念.许多 OO ...

  3. 线段树学习----C语言

    /* 线段树学习:如果一个节点为i,那么他的左孩子为2I+1,右孩子为2i+2: */ #include<stdio.h> #define min(a,b) a<b?a:b; ]; ...

  4. NIO学习笔记,从Linux IO演化模型到Netty—— 究竟如何理解同步、异步、阻塞、非阻塞

    我的观点 首先,分开各自理解. 1. 同步:描述两个(或者多个)个体之间的协调关系. 比如,单线程中,methodA调用了methodB,methodB返回后,methodA才往下执行,那么称A同步调 ...

  5. Vue中你可能认为是bug的情况原来是这样的

    前言 我们知道Vue框架剧本双向数据绑定功能,在我们使用方便的同时,还有一些细节问题我们并不知道,接下来一起探讨一些吧 双向数据绑定 js变量改变影响页面 页面改变影响js变量 Vue2是如何做到数据 ...

  6. OptaPlanner 7.32.0.Final版本彩蛋 - SolverManager之批量求解

    上一篇介绍了OptaPlanner 7.32.0.Final版本中的SolverManager接口可以实现异步求解功能.本篇将继续介绍SolverManager的另一大特性 - 批量求解. 适用场景 ...

  7. python——面向对象(3),搬家具

    """date: 2020.2.9搬家具:将小于房子剩余面积的家具搬进房子1.定义家具类,房屋类""" class Furniture(): ...

  8. 使用font-weight无法调节字体粗细的问题解决

    最近我遇到这样的问题,就是使用font-weight无法调节字体粗细. 据我所知,font-weight是用于调节字体粗细的,可选100.200.300.400(normal).500.600.700 ...

  9. SQL中的real、float、decimal、numeric数据类型区别

    概述: 浮点数据类型包括real型.float型.decimal型和numeric型.浮点数据类型用于存储十进制小数. 在SQL Server 中浮点数值的数据采用上舍入(Round up)的方式进行 ...

  10. idea 工具 听课笔记 首页

    maven 创建 javaWeb站点结构标准及异常权限调整 解决Intellij Idea下修改jsp页面不自动更新(链接 idea中使用github  提交 idea 从github.com上恢复站 ...