无向图的连通分量

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 @   蒟蒻爬行中  阅读(87)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示