标签:还需 rap rest 标准 png ace mamicode 复杂度 href
Detect Cycle in a Directed Graph
https://www.geeksforgeeks.org/detect-cycle-in-a-graph/
有向图里的环必须是 a->b b->c c->a 类似这种的环(包括自环)。
这学期刚上过算法,dfs遍历图会得到dfs tree(如果不是连通图就是forest),并提到了back edge的概念。如果dfs遍历图的时候,有back edge产生,那就说明一定有环。
写起来就按照标准的dfs写,需要一个visited数组来判断是否已经访问过。这里还需要一个set来记录递归过程中压栈的节点,以此判断是否是back edge。
注意不要想当然的直接用visited来判断,如果节点之前访问过就有环,这样是不过的,反例如 a->b->d a->c->d。
时间复杂度 O(V+E)
#include <iostream> #include <vector> #include <list> #include <unordered_set> using namespace std; class DirectedGraph{ int n; // # of nodes vector<list<int>> adj; // adjacency lists public: DirectedGraph(int N):n(N),adj(N,list<int>()){}; void addEdge(int u, int v){ // to add an edge u->v to graph adj[u].push_back(v); } bool isCyclic(){ //If has back edge, then has cycle vector<bool> visited(n,false); unordered_set<int> recStack; // recursion stack for (int i=0;i<n;++i){ if (dfs(i,visited,recStack)) return true; } return false; } bool dfs(int i, vector<bool> &visited, unordered_set<int> &recStack){ if (recStack.count(i)) return true; if (visited[i]) return false; visited[i] = true; recStack.insert(i); for (auto x:adj[i]) if (dfs(x,visited,recStack)) return true; recStack.erase(i); return false; } }; int main() { DirectedGraph g(4); g.addEdge(0, 1); //g.addEdge(0, 2); g.addEdge(1, 2); //g.addEdge(2, 0); g.addEdge(2, 3); //g.addEdge(3, 3); cout << g.isCyclic(); return 0; }
Detect Cycle In Directed/Undirected Graph
标签:还需 rap rest 标准 png ace mamicode 复杂度 href
原文地址:https://www.cnblogs.com/hankunyan/p/10962814.html