我是用邻接表和BFS做的,我看到很多人都是用DFS做的。不管了,抓到猫就是好猫。
这题主要是考察模板,只不过这个题需要解决如何判断它能不能转换成一棵树(即是不是连通的),并输出连通分量的个数。也是想了一下才想出来这个方法。
#include<iostream>
#include<queue>
#include<vector>
#include<set>
using namespace std;
struct node {
int id,h;
};
bool visited[10005]; //判断哪些结点遍历过,因为不连通的分量遍历不到,从而计算连通分量的个数
vector<node> Adj[10005]; //邻接表
int bfs(int id) {
bool vis[10005] = { false }; //函数内部变量,每次bfs都重新生成,与visited数组区分开
queue<node> q;
q.push(node{ id,1 });
vis[id] = visited[id]=true;
int height=1; //初始高度
while (!q.empty()) {
node top = q.front();
q.pop();
for (int i = 0; i < Adj[top.id].size(); i++) {
node next = Adj[top.id][i];
next.h = top.h + 1;
if (next.h > height) height = next.h;
if (vis[next.id] == false) { //有点容易写漏这里
q.push(next);
vis[next.id] = visited[next.id] = true;
}
}
}
return height;
}
int main() {
int n; cin >> n;
for (int i = 0; i < n - 1; i++) {
int a, b; cin >> a >> b;
Adj[a].push_back({ b,1 });
Adj[b].push_back({ a,1 });
}
int maxh = 0;
set<int> an;
int k = 0;
for (int i = 1; i <= n; i++) {
if (visited[i] == false) k++; //如果之前未访问到,说明是另一个连通分量的结点
int h = bfs(i);
if (h > maxh) {
maxh = h;
an.clear(); //如果最大高度更新,就把之前存的结点清除
an.insert(i);
}
else if (h == maxh) an.insert(i);
}
if (k > 1) printf("Error: %d components", k); //有多个连通分量
else {
for (auto it = an.begin(); it != an.end(); it++) {
cout << *it << endl;
}
}
return 0;
}
另外,用常规的DFS方法也做了一下,发现一样的思路有一个测试点会超时,是由于数据量大的时候,每次循环做一次memset很耗时。
#include<iostream>
#include<vector>
#include<set>
#include<cstring>
using namespace std;
const int maxv = 10005;
int G[maxv][maxv];
bool visited[maxv];
bool vis[maxv];
int n,num=0,maxh=0;
set<int> an;
void dfs(int id,int h) {
if (h > maxh) {
maxh = h;
an.clear();
an.insert(id);
}
else if (h == maxh) an.insert(id);
vis[id] =visited[id]= true;
for (int i = 1; i <= n; i++) {
if (vis[i] == false&&G[id][i]) {
dfs(i, h + 1);
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n - 1; i++) {
int a, b; cin >> a >> b;
G[a][b] = G[b][a] = 1;
}
for (int i = 1; i <= n; i++) {
memset(vis, false, sizeof(vis)); //重置为false
if (visited[i] == false) num++;
dfs(i, 1);
}
if (num > 1) printf("Error: %d components", num);
else {
for (auto it = an.begin(); it != an.end(); it++) {
cout << *it << endl;
}
}
return 0;
}