Iterative DFS on the graph with post-visit ordering

Recently, I'm studying about SCC(Strongly Connected Component) related subjects. Kosaraju's algorithm and Tarjan's algorithm are two representative algorithm to calculate SCC of graph.

Kosaraju's algorithm requires post-visit order list of DFS.
With recursive DFS, it's straightforward. But conventional iterative DFS algorithm can't calculate post-visit order.
Since that it doesn't store any information about vertices that previously visited.
Although I've googled several hrs to find nice implementation, I failed it.

So, I implemented with additional depth stack and parent array. If you have idea for any furture simplification or optimization, please mail me!
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;

int main() {

    int N; // Number of vertices
    int M; // Number of edges
    vector<vector<int>> graph; // Adjacency list of graph

    stack<int> dfs; // Stack for dfs
    stack<int> depth; // Stack for storing depth from start vertex
    
    scanf("%d %d", &N, &M); 

    int *visited = new int[N](); 
    int *parent = new int[N]();

    graph.resize(N + 1); 

    for(int i = 0; i < M; i++) {
        int f, t;
        scanf("%d %d", &f, &t);
        graph[f].push_back(t); 
    }

    // DFS visit priority by vertex index 
    for(int i = 0; i < N; i++) sort(graph[i].begin(), graph[i].end());

    for(int i =0; i < N; i++) parent[i] = -1; 
    dfs.push(1); // Set start vertex 

    while(!dfs.empty()) { 

        int vertex = dfs.top();
        dfs.pop();

        // If topological order of current vertex is smaller than
        // depth stack, then pop elements of depth stack until
        // those are equal.
        while(!depth.empty() && parent[vertex] != depth.top()) {
            printf("%d\n", depth.top());
            depth.pop(); 
        }

        depth.push(vertex);
        
        for(int i = 0; i < graph[vertex].size(); i++) {
            int neighbor = graph[vertex][i]; 
            if(!visited[neighbor]) {
                dfs.push(neighbor); 
                parent[neighbor] = vertex;   
            }
        }

        visited[vertex] = 1; 
    }

    // Clean depth stack
    while(!depth.empty()) { 
        printf("%d\n", depth.top());
        depth.pop();
    }

    return 0;
}
Example Data
7 9
1 2
2 1
2 4
4 3
3 5
5 4
2 6
6 7
7 6
Result
7
6
5
3
4
2
1

댓글

이 블로그의 인기 게시물

Proof of well-known 'Intersection Of Three Planes' formula.

Linux에서 특정한 디렉토리가 차지하는 용량을 효율적이고, 빠르게 계산하는 법(Fast, efficient way to calculate directory size recursively on linux)

'Index type not supported yet' error when doing QR factorization using Eigen and SuiteSparseQR