【题目大意】

给出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. Nginx 部署及配置

    Tengine + Luajit2 系统账号及环境配置 $ sudo useradd -g 100 -u 200 user_00 $ sudo groupadd -g 300 www $ sudo u ...

  2. 云服务器InfluxDB & Chronograf配置

    环境: 阿里云服务器 Ubuntu 18.04.3 LTS InfluxDB 1.7.10 (截至2020.2.20最新版) chonograf 1.8.0 (2020.2.19推出) 配置建议: 不 ...

  3. LeetCode29 Medium 不用除号实现快速除法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 链接 Divide Two Integers 难度 Medium 描述 给定两个整数,被除数和除数,要求在不使用除号的情况下计算出两数的商 ...

  4. 终于解决 k8s 集群中部署 nodelocaldns 的问题

    自从开始在 kubernetes 集群中部署 nodelocaldns 以提高 dns 解析性能以来,一直被一个问题困扰,只要一部署 nodelocaldns ,在 coredns 中添加的 rewr ...

  5. VNC 远程桌面 连接(安装桌面程序)

    1.修改linux启动方式       # vi /etc/inittab         将3改为5     id:5:initdefault:   2.关闭防火墙(或者单独打开接口)     #s ...

  6. linux系统的启动流程梳理

    1. 不同版本的linux系统的启动流程 1.1 centos6.x系统的启动流程 其详细启动步骤如下: 1)开机,BIOS自检,检查各个硬件是否正常 2)读取硬盘MBR信息,引导系统启动 3)加载g ...

  7. docker安装db2数据库

    查询可安装的db2镜像 # docker search db2 [root@docker-servers ~]# docker search db2 INDEX NAME DESCRIPTION ST ...

  8. java.net.SocketTimeoutException: Read timed out 异常排查

    问题描述:使用RestTemplate调用接口出现该异常,相关调用代码: ResponseEntity<ResultVO> responseEntity; try { responseEn ...

  9. python3-cookbook笔记:第八章 类与对象

    python3-cookbook中每个小节以问题.解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构.函数.类等特性在某类问题上如何更好地使 ...

  10. 【React Native】某个页面禁用物理返回键

    1.引入组件 import { BackHandler, } from 'react-native'; 2.添加监听 componentDidMount(): void { BackHandler.a ...