Algorithm/알고리즘 이론

강한연결요소 : Strongly Connected Component

계속지나가기 2021. 9. 5. 11:36
반응형

강한연결요소 : Strongly Connected Component

 

Concept


방향 그래프 G의 임의의 노드 쌍 u,v에 대해 u->v, v->u로 가는 경로가 존재하면

G는 Strongly Connected 되었다고 한다

 

따라서 G의 u->v 로 가는 경로가 있을 때, 엣지의 방향을 정반대로 바꾼 transpose G에도 u->v로 가는 경로가 있다면 두 노드 사이에 사이클이 있어 SCC를 만족한다

 

Kosaraju's Algorithm


#include <iostream>
#include <vector>
#include <stack>
#include <set>

#define MAX 10001
using namespace std;

int n, out_len;
bool check[MAX], check2[MAX];
vector<int> r[MAX], r2[MAX];
stack<int> S, S2;
set<int> out[MAX];

// for Graph G
void dfs(int x){
    check[x] = true;
    for(auto iter = r[x].begin(); iter != r[x].end(); iter++)
        if (check[*iter] == false)
            dfs(*iter);
    S.push(x); //stack for descending order that DFS's finish time
}
// for transpose Grpah G
void dfs2(int x, int w){
    check2[x] = true;
    for(auto iter = r2[x].begin(); iter != r2[x].end(); iter++)
        if (check2[*iter] == false)
            dfs2(*iter, w);
    out[w].insert(x);
}

int main(void){
    int x, y, m;
    
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        cin >> x >> y;
        r[x].push_back(y); // Graph G
        r2[y].push_back(x); // transpose Graph G^T
    }
    // first dfs to G
    for(int i = 1; i <= n; i++)
        if(check[i] == false)
            dfs(i);
    
    // perform dfs in G^T for G's finish time descending order
    while(!S.empty()){
        int x = S.top();
        S.pop();
        
        if (check2[x]) // if already visited node, pass
            continue;
        
        dfs2(x,++out_len);
    }
    sort(out + 1, out + out_len + 1);
    cout << out_len << '\n'; // the number of SCC groups
    
    for(int i = 1; i <= out_len; i++){
        cout << "GROUP " << i << ": ";
        for(auto iter = out[i].begin(); iter != out[i].end(); iter++)
            cout << *iter << ' ';
        cout << "\n";
    }
    
}
반응형