赞
踩
给定有向图,检查该图是否包含循环。如果给定图包含至少一个循环,则函数应返回true,否则返回false。
对一个图进行DFS, 则DFS的路径可以生成一个棵树。
对于DFS树上的结点,如果存在指向祖先的边或指向自己边,则图存在回路。(这种边叫做后向边)
下面通过图来描述一下:
有向图,如下。
其DFS树为:
但是当你DFS到3结点时 会存在后向边,如图:
所以这个有向图存在环路
首先需要两个辅助数组。
vis数组:用来标记节点是否已被访问。
recStack数组(或集合):一个用来标记递归栈中的节点(或者说递归过程中的节点)。
isCyclic
返回true。否则返回false。其实isCyclicUtil就是DFS函数稍加修改。
#include<bits/stdc++.h> using namespace std; const int N = 105; vector<vector<int> > g(N); bool isCyclicUtil(int v, bool vis[],bool recStack[]) { if (!vis[v]) { vis[v] = recStack[v] = true; for(int i = 0;i < g[v].size();++ i) { if (!vis[g[v][i]] && isCyclicUtil(g[v][i], vis, recStack)) return true; else if (recStack[g[v][i]]) return true; } } recStack[v] = false; return false; } bool isCyclic(int n) { bool vis[n],recStack[n]; for(int i = 0;i < n;++ i) vis[i] = recStack[i] = false; for(int i = 0;i < n;++ i) { if (isCyclicUtil(i, vis, recStack)) return true; } return false; } int main() { int n,m; cin >> n >> m; for(int i = 0;i < m;++ i) { int from, to; cin >> from >> to; g[from].push_back(to); } cout << (isCyclic(n) ? "yes" : "no"); return 0; } /* input output */
时间复杂度: O ( V + E ) O(V + E) O(V+E)。
空间复杂度: O ( V ) O(V) O(V)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。