⚠️此题不能使用邻接矩阵,否则内存会超限,得使用邻接表。
解决思路:
- 连通分支+广度优先遍历
- 首先广度优先搜索判断它有几个连通分量。如果有多个,那就输出Error: x components,如果只有一个,就两次广度优先搜索,先从一个结点bfs后保留最高高度拥有的结点们,然后从这些结点中的其中任意一个开始bfs得到最高高度的结点们,这两个结点集合的并集就是所求
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
const int maxn = 10001;
const int INF = 1000000000;
int n;
//bool G[maxn][maxn];
vector<int> G[maxn];
bool vis[maxn] = {false};
struct Node
{
int idx;
int layer;
};
bool cmp(int n1, int n2) {
return n1 < n2;
}
int maxlayer = 1;
vector<Node> allnodes;
void bfs(int u) {
allnodes.clear();
fill(vis, vis+maxn, 0);
maxlayer = 1;
queue<Node> q;
Node node;
node.idx = u;
node.layer = 1;
q.push(node);
allnodes.push_back(node);
vis[u] = true;
while(!q.empty()) {
Node top = q.front();
q.pop();
for (int i = 0; i < G[top.idx].size(); ++i)
{
int v = G[top.idx][i];
if(!vis[v]) {
Node temp;
temp.idx = v;
temp.layer = top.layer+1;
q.push(temp);
vis[temp.idx] = true;
allnodes.push_back(temp);
if(temp.layer > maxlayer) {
maxlayer = temp.layer;
}
}
}
}
}
void simple_bfs(int u) {
queue<int> q;
q.push(u);
vis[u] = true;
while(!q.empty()) {
int top = q.front();
q.pop();
for (int i = 0; i < G[top].size(); ++i)
{
int v = G[top][i];
if(!vis[v]) {
q.push(v);
vis[v] = true;
}
}
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n-1; ++i)
{
int start, end;
scanf("%d %d", &start, &end);
G[start].push_back(end);
G[end].push_back(start);
}
// 如果只含一个点
if(n == 1) {
printf("1\n");
return 0;
}
// 这里还有问题,因为如果有环,不能检测出来, 但是恰好 边数=n-1,当只存在一个连通分支的时候,不可能会存在环。
int cnt = 0;
for (int i = 1; i <= n; ++i)
{
if(!vis[i]) {
simple_bfs(i);
cnt++;
}
}
if(cnt > 1) {
printf("Error: %d components\n", cnt);
return 0;
}
int bestlayer=0;
set<int> bestnodes;
bfs(1);
for (int i = allnodes.size()-1; i >= 0; --i)
{
if(allnodes[i].layer >= maxlayer) {
bestnodes.insert(allnodes[i].idx);
}
else break;
}
bfs(*bestnodes.begin());
for (int i = allnodes.size()-1; i >= 0; --i)
{
if(allnodes[i].layer >= maxlayer) {
bestnodes.insert(allnodes[i].idx);
}
else break;
}
for (set<int>::iterator it = bestnodes.begin(); it != bestnodes.end(); it++)
{
printf("%d\n", *it);
}
}
网友评论