CC算法
算法实现
#include "graph.h"
/*
CC算法比union-find算法更慢.CC算法需要构建好一幅图
但是union-find算法是一种动态算法,可以在添加边的时候去检查两个顶点是否连通
*/
class CC { // 其实就是计算连通分量
public:
CC(Graph G) {
marked_.resize(G.V(), false);
id_.resize(G.V());
for (int i = 0; i < G.V(); i++) {
if (!marked_[i]) {
dfs(G, i);
count_++;
}
}
}
bool Connect(int w, int v) { return id_[w] == id_[v]; }
void dfs(Graph& G, int v) {
marked_[v] = true;
id_[v] = count_;
for (auto e : G.GetAdj(v)) {
if (!marked_[e]) {
dfs(G, e);
}
}
}
private:
std::vector<bool> marked_;
std::vector<int> id_; // 记录的是该顶点属于哪一个连通分量
int count_;
};
int main() {
Graph graph(13);
graph.ReadTxt("./map.txt");
graph.Show();
CC c(graph);
}
可以解决连通区域个数,以及判断顶点是否连通
Graph结构如下
#ifndef _GRAPH_H_
#define _GRAPH_H_
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#include <vector>
class Graph {
public:
Graph(int v) : V_(v), E_(0) {
// 分配空间
adj.resize(V_); // 代表有V个顶点
}
void AddEdge(int v, int w) { // 添加边
adj[v].push_back(w);
// adj[w].push_back(v);
E_++;
}
std::list<int> GetAdj(int v) { return adj[v]; }
void ReadTxt(const std::string& file) {
std::ifstream in;
in.open(file, std::ios::in);
if (!in.is_open()) {
std::cout << "Open " << file << " Failed" << std::endl;
return;
}
char ch;
int V;
int sum = 0;
bool is_num = false;
while (in.read(&ch, 1)) {
if (ch == EOF) {
break;
} else if (ch == '\n') {
AddEdge(V, sum);
is_num = false;
sum = 0;
} else if (ch == ':') {
V = sum;
sum = 0;
is_num = false;
} else if (ch >= '0' && ch <= '9') {
sum = sum * 10 + ch - '0';
is_num = true;
} else if (ch == ' ') {
if (is_num) {
AddEdge(V, sum);
sum = 0;
is_num = false;
}
}
}
}
void Show() {
std::cout << "V: " << V_ << " E: " << E_ << std::endl;
int index = 0;
for (auto& a : adj) {
std::cout << "顶点: [" << index++ << "] ";
for (auto v : a) {
std::cout << v << " ";
}
std::cout << std::endl;
}
}
inline int V() { return V_; }
inline int E() { return E_; }
private:
int V_; // 顶点个数
int E_; // 边的数目
std::vector<std::list<int>> adj; //邻接表
};
#endif
Graph代表的是无向图
map.txt内容如下
0: 6 2 1 5
1: 0
2: 0
3: 5 4
4: 5 6 3
5: 3 4 0
6: 0 4
7: 8
8: 7
9: 11 10 12
10: 9
11:9 12
12: 11 9