c++graph-algorithmgraph-traversalcycle-detection

Finding the cycle in a directed graph


I was solving a problem to determine whether a graph contains a cycle. I solved it using the coloring method (in the visited array I will mark, 0 if it has never visited, 1 if it is visited, and 2 if the tour of vertex is done) for this I wrote the code:

#include <bits/stdc++.h>
using namespace std;

vector<int> adj[20005];
int vis[20005];
int chk = 0;
void dfs(int u){
    if(vis[u]==1) {
        chk = 1;
        return;
    }
    if(vis[u]==2) return;
    vis[u] = 1;
    for(auto v:adj[u]) dfs(v);
    vis[u] = 2;
} 

int main(){
    int N, M; cin>>N>>M;
    for(int i = 0; i<M; i++){
        int p, q; cin>>p>>q;
        adj[p].push_back(q);
    }
    for(int i = 1; i<=N; i++){
        if(vis[i]==1) break;
        if(!vis[i]) dfs(i);
    }   
    cout<<(chk?"Yes\n":"No\n");
}

Now, I'm thinking, if there's a way to write the cycle which has been detected. I know most people will say DFS and backtracking and it's very intuitive. But want to know how do I implement it.


Solution

  • par[v] - parent node of v, pr - previously visited node:

    void dfs(int u, int pr = -1){
        if(vis[u]==1) {
            vector<int> cycle();
            int cur = pr;
            while(cur != u) {
                cycle.push_back(cur);
                cur = par[cur]
            }
            cycle.push_back(u);
            chk = 1;
            return;
        }
        if(vis[u]==2) return;
        vis[u] = 1;
        par[u] = pr;
        for(auto v:adj[u]) dfs(v, u);
        vis[u] = 2;
    }