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!
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 6Result
7 6 5 3 4 2 1
댓글
댓글 쓰기