目录
kahn算法
先统计入度
然后选择入度为0的,更新入度
直到队列空了
如果出队次数等于顶点数,那就是一个拓扑排序,否则有环
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N = 10000;
vector<int> edge[N];
bool topological_sort(const int& n, int top_sort[]) {
int in[N] = {};
for (int u = 0; u < n; ++u) {
for (int& v : edge[u]) {
++in[v];
}
}
queue<int> q;
for (int u = 0; u < n; ++u) {
if (in[u] == 0) {
q.push(u);
}
}
int cnt = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
top_sort[cnt] = u;
++cnt;
for (int& v : edge[u]) {
--in[v];
if (in[v] == 0) {
q.push(v);
}
}
}
return cnt == n;
}
int main() {
edge[0] = { 1 };
//edge[1] = { 0 };
int a[2];
cout << topological_sort(2, a) << endl;
return 0;
}
dfs
染色
1是正在访问,0是未访问,-1是访问完了
如果访问的节点正在被访问就是有环
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 10000;
vector<int> edge[N];
int visit[N];
bool dfs(const int& u, int top_sort[], int& cnt) {
//正在访问
visit[u] = 1;
for (int& v : edge[u]) {
//v正在被访问,有环
if (visit[v] == 1) {
return false;
}
else if (visit[v] == 0 && !dfs(v, top_sort, cnt)) {
//失败
return false;
}
}
//访问过了
visit[u] = -1;
top_sort[cnt] = u;
++cnt;
return true;
}
bool topological_sort(const int& n, int top_sort[]) {
//初始化为访问过了
memset(visit, 0, sizeof(visit));
int cnt = 0;
for (int i = 0; i < n; ++i) {
if (visit[i] == 0 && !dfs(i, top_sort, cnt)) {
return false;
}
}
int i = 0;
int j = n - 1;
//逆拓扑转拓扑序列
while (i < j) {
swap(top_sort[i], top_sort[j]);
++i;
--j;
}
return true;
}
int main() {
edge[0] = { 1 };
edge[1] = { 0 };
int a[2];
cout << topological_sort(2, a) << endl;
return 0;
}