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

댓글

이 블로그의 인기 게시물

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

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

선형대수와 군