解决这个问题的算法的思路是对一个节点u进行dfs,判断是否能从u回到自己这个节点,即是否存在从u到u的回路。
我们可以用一个color数组代表每个结点的状态,-1代表还没被访问,0代表正在被访问,1代表访问结束
如果一个状态为“0”的结点,与他相连的结点状态也为“0”的话就代表有环,这个可以用dfs实现
#include <iostream>
#include <vector>
#include <string.h>
#include <stdio.h>
using namespace std;
/*
color代表每个结点的状态,-1代表还没被访问,0代表正在被访问,1代表访问结束
如果一个状态为“0”的结点,与他相连的结点状态也为0的话就代表有环,这个可以用dfs实现
*/
const int N = (int)1e5 + 10;
vector <int> vec[N];
int color[N];
bool dfs(int u) {
color[u] = 0; // 0表示正在访问
for (int v: vec[u]) {
if (color[v] == 0) { //如果正在访问的点又被访问到则代表有环
return false;
} else if (color[v] == -1) { // -1代表还没有访问
if (!dfs(v)) {
return false;
}
}
}
color[u] = 1; // 1代表访问结束
return true;
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int from, to;
cin >> from >> to;
vec[from].push_back(to);
}
memset(color, -1, sizeof(color));
auto check = [&] () -> bool {
for (int i = 1; i <= n; i++) {
if (color[i] == -1) {
if (!dfs(i)) {
return false;
}
}
}
return true;
};
puts(check() ? "no have" : "have");
return 0;
}
/*
int n,m;
for(i -> m)
vec[u].p(v)
dfs(x)
if(flag) return
color x <- 0;
for i -> size
if color u = -1
dfs u
else if color u = 0
flag = true
return
color x = 1
*/