1021 Deepest Root (25分)

我是用邻接表和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;
}
发布了26 篇原创文章 · 获赞 5 · 访问量 439

猜你喜欢

转载自blog.csdn.net/weixin_43590232/article/details/104043276