算法导论-第22章-基本的图算法:强连通分量(深度优先遍历基础上)C++实现

#include <iostream>
using namespace std;

struct Vertex {
	int index{ -1 };
	Vertex* next{ nullptr };
};

enum class COLOR {
	WHITE, GRAY, BLACK
};

struct Node {
	int d{};
	int f{};
	COLOR color{ COLOR::WHITE };
};

void recurse_delete(Vertex* v) {
	if (v->next) {
		recurse_delete(v->next);
	}
	else {
		delete v;
	}
}

void delete_list(Vertex* V, size_t n) {
	Vertex* head{};
	Vertex* p{};
	for (int i = 0; i < n; ++i) {
		head = &V[i];
		if ((p = head->next)) {
			recurse_delete(p);
		}
	}
	delete[]V;
}

void insert(Vertex* V, int from, int to) {
	Vertex* head = &V[from];
	Vertex* p = head->next;
	head->next = new Vertex{};
	head->next->index = to;
	head->next->next = p;
}

void DFS_VISIT(Vertex* V, Node* N, int u, int& time) {
	time++;
	N[u].color = COLOR::GRAY;
	N[u].d = time;
	Vertex* head = &V[u];
	Vertex* p = head->next;
	while (p) {
		if (N[p->index].color == COLOR::WHITE) {
			DFS_VISIT(V, N, p->index, time);
		}
		p = p->next;
	}
	N[u].color = COLOR::BLACK;
	time++;
	N[u].f = time;
}

void DFS(Vertex* V, Node* N, size_t n, int start, int& time) {
	if (N[start].color == COLOR::WHITE) {
			DFS_VISIT(V, N, start, time);
	}
	for (int i = 0; i < n; ++i) {
		if (N[i].color == COLOR::WHITE) {
			DFS_VISIT(V, N, i, time);
		}
	}
}

void sort_f(int* f, Node* N, size_t n) {
	int* flag = new int[n]{};
	for (int i = 0; i < n; ++i) {
		int f_max{};
		int max_index{};
		for (int j = 0; j < n; ++j) {
			if (N[j].f > f_max && !flag[j]) {
				f_max = N[j].f;
				max_index = j;
			}
		}
		f[i] = max_index;
		flag[max_index] = 1;
	}
}

void built_VT(Vertex* VT, Vertex* V, int* Matrix_T, int* f, size_t n) {
	Vertex* head{};
	Vertex* p{};
	for (int i = 0; i < n; ++i) {
		head = &VT[i];
		p = head->next;
		for (int j = n - 1; j >= 0; --j) {
			if (Matrix_T[i * n + f[j]] == 1) {
				head->next = new Vertex{};
				head->next->index = f[j];
				head->next->next = p;
				p = head->next;
			}
		}
	}
}

void initial_nodes_color(Node* N, size_t n) {
	for (int i = 0; i < n; ++i) {
		N[i].color = COLOR::WHITE;
	}
}

void DFS_VISIT_T(Vertex* VT, Node* N, size_t n, int u) {
	cout << u << " ";
	N[u].color = COLOR::GRAY;
	Vertex* head = &VT[u];
	Vertex* p = head->next;
	while (p) {
		if (N[p->index].color == COLOR::WHITE) {
			DFS_VISIT_T(VT, N, n, p->index);
		}
		p = p->next;
	}
	N[u].color = COLOR::BLACK;
}

void DFS_T(Vertex* VT, Node* N, int* f, size_t n) {
	DFS_VISIT_T(VT, N, n, f[0]);
	cout << endl;
	for (int i = 0; i < n; ++i) {
		if (N[f[i]].color == COLOR::WHITE) {
			DFS_VISIT_T(VT, N, n, f[i]);
			cout << endl;
		}
	}
}

void STRONG_CONNECTED_COMPONENTS(Vertex* V, int* Matrix_T, size_t n) {
	int start{};
	Node* N = new Node[n] {};
	cout << "please choose which vertex do you want to start DFS :" << endl;
	cin >> start;
	int time{};
	DFS(V, N, n, start, time);
	int* f_array = new int[n]{};
	sort_f(f_array, N, n);
	Vertex* VT = new Vertex[n] {};
	built_VT(VT, V, Matrix_T, f_array, n);
	initial_nodes_color(N, n);
	cout << "the strong connected components as follow :" << endl;
	DFS_T(VT, N, f_array, n);
	delete[]f_array;
	delete[]N;
	delete_list(VT, n);
}

int main(int argc, char* argv[]) {
	size_t vertex_size{};
	cout << "please input the numbers of vertexs :" << endl;
	cin >> vertex_size;
	Vertex* V = new Vertex[vertex_size] {};
	int* Matrix_T = new int[vertex_size * vertex_size] {};
	cout << "please enter the edges : (eg : 0 1 presents there is a edge between v0 and v1, and end with -1 -1)" << endl;
	int from{};
	int to{};
	while (true) {
		cout << "edge :" << endl;
		cin >> from >> to;
		if (from != -1 && to != -1) {
			Matrix_T[to * vertex_size + from] = 1;
			insert(V, from, to);
		}
		else {
			break;
		}
	}
	STRONG_CONNECTED_COMPONENTS(V, Matrix_T, vertex_size);
	delete_list(V, vertex_size);
	delete[]Matrix_T;
	return 0;
}

点赞