[c++] 강한 연결 요소 찾기 알고리즘

강한 연결 요소(Strongly Connected Components, SCC)는 그래프 이론에서 중요한 개념 중 하나입니다. 그래프 내에서 SCC를 찾는 것은 매우 유용하며, 이를 활용하여 다양한 문제들을 해결할 수 있습니다. 이번 글에서는 강한 연결 요소를 찾는 알고리즘을 살펴보겠습니다.

강한 연결 요소란 무엇인가요?

강한 연결 요소는 방향 그래프에서의 연결이 강한 부분을 의미합니다. 즉, 한 SCC에 속한 임의의 두 정점 u와 v에 대해 u에서 v로 가는 경로와 v에서 u로 가는 경로가 모두 존재해야 합니다.

코사라주 알고리즘

코사라주 알고리즘은 강한 연결 요소를 찾는 데 사용되는 대표적인 알고리즘 중 하나입니다. 이 알고리즘은 다음과 같은 단계로 수행됩니다.

  1. 주어진 그래프에 대해 DFS(Depth-First Search)를 수행하여 각 정점에 탐색 순서를 기록합니다.
  2. 주어진 그래프의 간선 방향을 뒤집어 역방향 그래프를 생성합니다.
  3. 역방향 그래프에 대해 다시 DFS를 수행하되, 탐색 순서의 역순으로 탐색합니다.
  4. 위 과정을 통해 찾은 강한 연결 요소들이 SCC입니다.

예시 코드

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>

using namespace std;

vector<vector<int>> graph, reverseGraph;
vector<bool> visited;
stack<int> s;

void dfs(int v) {
    visited[v] = true;
    for (int next : graph[v]) {
        if (!visited[next]) {
            dfs(next);
        }
    }
    s.push(v);
}

void reverseDfs(int v, vector<int>& scc) {
    visited[v] = true;
    scc.push_back(v);
    for (int next : reverseGraph[v]) {
        if (!visited[next]) {
            reverseDfs(next, scc);
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;

    graph.resize(n + 1);
    reverseGraph.resize(n + 1);
    visited.assign(n + 1, false);

    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        graph[a].push_back(b);
        reverseGraph[b].push_back(a);
    }

    for (int i = 1; i <= n; ++i) {
        if (!visited[i]) {
            dfs(i);
        }
    }

    visited.assign(n + 1, false);
    vector<vector<int>> scc;
    while (!s.empty()) {
        int v = s.top();
        s.pop();
        if (!visited[v]) {
            vector<int> curScc;
            reverseDfs(v, curScc);
            scc.push_back(curScc);
        }
    }

    for (auto& component : scc) {
        sort(component.begin(), component.end());
        for (int v : component) {
            cout << v << " ";
        }
        cout << "\n";
    }

    return 0;
}

위의 예시 코드는 코사라주 알고리즘을 사용하여 강한 연결 요소를 찾는 코드입니다.

마치며

강한 연결 요소는 다양한 분야에서 활용되며, 그래프 이론에서 중요한 개념 중 하나입니다. 코사라주 알고리즘을 통해 강한 연결 요소를 효과적으로 찾을 수 있으며, 이를 응용하여 실제 문제를 해결하는 데 활용할 수 있습니다.

참고 문헌