无向图的连通分量

8-1:无向图的连通分量
【问题描述】求解无向图的连通分量。
【输入形式】第一行:顶点数 边数;第二行:顶点;第三行及后面:边(每一行一条边)
【输出形式】分量:顶点集合(顶点按从小到大排序输出)(每个连通分量输出占用一行)
【样例输入】

6 5
ABCDEF
A B
A E
B E
A F
B F

【样例输出】

1:ABEF
2:C
3:D

【代码】
【适配c++98版本】

#include<bits/stdc++.h>
using namespace std;

int n, e;	//节点数和边数
char x, y;	//边的两个节点
string v;	//节点集合
vector<int> p;	//父节点数组

//递归查找根节点(路径压缩)
int find(int x) {
	if (p[x] != x)	p[x] = find(p[x]);
	return p[x];
}

int main()
{
	cin >> n >> e >> v;
	//初始化并查集,每个节点自身为一集合
	p.resize(n);
	for (int i = 0; i < n; i++) p[i] = i;
	//合并节点
	while (e--) {
		cin >> x >> y;
		p[find(x - 'A')] = find(y - 'A');
	}
	//将属于相同集合的节点归类
	vector<vector<char> > m(n);	//集合节点数组
	for (int i = 0; i < n; i++) {
		char root = find(i) + 'A';		//找到节点所在集合的根节点
		m[root - 'A'].push_back(v[i]);	//将节点添加到对应的集合中
	}
	int id = 1;
	sort(m.begin(), m.end());	//按字典序排序
	for (size_t i = 0; i < m.size(); i++) {
		if (!m[i].empty()) {
			cout << id++ << ":";
			//获取当前集合的节点列表
			for (size_t j = 0; j < m[i].size(); j++)
				cout << m[i][j];
			puts("");
		}
	}
	return 0;
}

【使用unordered_map的版本】
本地能过样例,但因为cg上c++98不接受unordered_map,试了一下tr1/unordered_map,铩羽而归
但写都写了,在这里存个档权当留念 : (

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

int n, e;
char x, y;
string v;
unordered_map<char, int> p;
unordered_map<char, vector<char>> m;

int find(char x) {
	if (p[x] != x)	p[x] = find(p[x]);
	return p[x];
}

int main()
{
	cin >> n >> e >> v;
	for (int i = 0; i < n; i++) p[v[i]] = v[i];
	while (e--) {
		cin >> x >> y;
		p[find(x)] = find(y);
	}
	for (auto& i : p) {
		char root = find(i.first);
		m[root].push_back(i.first);
	}
	int id = 1;
	for (auto& i : m) {
		cout << id++ << ":";
		vector<char> node = i.second;
		for (char c : node)	cout << c;
		cout << endl;
	}
	return 0;
}
posted @ 2023-12-22 09:29  蒟蒻爬行中  阅读(156)  评论(0)    收藏  举报