Used to determine the precursor relationship.
For example, a <b, c <d, c <b can determine
a <c <b <d
or
c <a <b <d
If there is no ring, there must be such a chain, but if there is a ring, topological sorting cannot be performed. In this example, a> b and b> a cannot be achieved;
Use dfs for
Fake code
//判断是否有环(true 没有; false 有)
bool dfs(u) {
本趟节点标记;
for(遍历以u为入弧的定点){
if(是本趟节点)return false;
else if(如果没访问过) {
if(子节点有环)return false;
}
}
//表示这个节点的到底都没有环
倒着将沿途的节点加入拓扑队列 //因为这是递归的返回,就是到头回来的过程
return true;
}
bool topoSort(){
for(遍历节点){
if(没访问过){
if(有环) return false;
}
}
//所有节点都没环
return true;
}
两句if 可以合成为
if(没访问过 && 有环)return false;
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100;
int c[maxn];
int topo[maxn], t, n;
int G[maxn][maxn];
bool dfs(int u)
{
c[u] = -1;
for(int v = 0; v < n; v++)
{
if(G[u][v])
{
if(c[v] < 0)
return false;
else if(!c[v] && !dfs(v))
return false;
}
}
c[u] = 1;
topo[--t] = u;
return true;
}
bool topoSort()
{
t = n;
memset(c,0,sizeof(c));
for(int u = 0; u < n; u++){
if(!c[u] && !dfs(u))
return false;
}
return true;
}
int main()
{
char ch[100] = {
'a', 'b', 'c', 'd'};
n = 4;
G[0][1] = 1;
//G[1][0] = 1;
G[2][1] = 1;
G[3][2] = 1;
if(!topoSort()){
printf("无法拓扑排序\n");
return 0;
}
for(int i = 0; i < 4; i++){
printf("%c ", ch[topo[i]]);
}
printf("\n");
}
The most exciting part of this code is to use c[u] = -1 to determine whether there is a loop in the result of this trip.
Different from the classic dfs flag array, two values are used to represent different meanings.
c[u] = 0: Indicates that every visit
c[u] = 1: Indicates that the node above the vertex has been visited
c[u] = -1: Indicates whether the dfs has been visited this time