---
# System prepended metadata

title: 利用DFS尋找Strongly Connected Component

---

# 利用DFS尋找Strongly Connected Component
## 參考網站
[Graph: 利用DFS尋找Strongly Connected Component(SCC)](http://alrightchiu.github.io/SecondRound/graph-li-yong-dfsxun-zhao-strongly-connected-componentscc.html)
## 步驟
1. 對G做第一次DFS，順序隨便
2. 按照finish陣列將vertex由小到大排序
3. 依照第二步得出的vertex順序，由小到大對G做第二次DFS
4. 按照finish陣列將vertex由小到大排序
5. 依照第四步得出的vertex順序，由大到小對gT做DFS
6. 用步驟五得到的finish陣列即可依照參考網站教學將SCCs分開

***主要是依照這個圖的概念分離SCCs***
![image](https://hackmd.io/_uploads/BysmNaeST.png)
（圖片來源：[Graph: 利用DFS尋找Strongly Connected Component(SCC)](http://alrightchiu.github.io/SecondRound/graph-li-yong-dfsxun-zhao-strongly-connected-componentscc.html)）



## Code
```cpp=
#include <iostream>
#include <vector>
#include <string.h>
#include <set>

void DFS(int root, bool* state, int* finish, int* start, std::vector<std::vector<int>>& E, int& findOrder);
void bubbleSort(int* arr, int* cmp_arr, int len);

int main() {
    
    int n;
    std::cin >> n;

    std::vector<std::vector<int>> E;
    std::vector<std::vector<int>> eT;
    int findOrder;
    bool state[n];
    int finish[n], vertexOrder[n], start[n];

    // initialize
    for (int i = 0; i < n; i++) vertexOrder[i] = i;
    for (int i = 0; i < n; i++) {
        std::vector<int> newVector;
        E.push_back(newVector);
        eT.push_back(newVector);
        for (int j = 0; j < n; j++) {
            E[i].push_back(0);
            eT[i].push_back(0);
        }
    }
    int from, to;
    while (std::cin >> from >> to) {
        E[from][to] = 1;
        eT[to][from] = 1;
    }

    
    // 對G做第一次DFS
    findOrder = 1;
    memset(state, 0, sizeof(state));
    for (int i = 0; i < n; i++) // 順序任意
        if (!state[i]) DFS(i, state, finish, start, E, findOrder);

    // 按照finish由小到大排序
    bubbleSort(vertexOrder, finish, n);

    
    // 對G做第二次DFS
    findOrder = 1;
    memset(state, 0, sizeof(state));
    for (int i = 0; i < n; i++) // 按照finish由小到大
        if (!state[vertexOrder[i]]) DFS(vertexOrder[i], state, finish, start, E, findOrder);

    // 按照finish由小到大排序
    bubbleSort(vertexOrder, finish, n);

    
    // 對gT做DFS
    findOrder = 1;
    memset(state, 0, sizeof(state));
    for (int i = n - 1; i >= 0; i--) // 按照finish由大到小
        if (!state[vertexOrder[i]]) DFS(vertexOrder[i], state, finish, start, eT, findOrder);

    // 按照finish由小到大排序
    bubbleSort(vertexOrder, finish, n);

    
    // create SCCs set
    std::vector<std::set<int>> SCCsVertices;
    int back;

    for (int i = 0; i < n; i++) {
        if (i == 0) {
            back = finish[vertexOrder[i]];
            SCCsVertices.push_back(std::set<int>());
            SCCsVertices[SCCsVertices.size() - 1].insert(vertexOrder[i]);
        }
        else if (start[vertexOrder[i]] > back) {
            back = finish[vertexOrder[i]];
            SCCsVertices.push_back(std::set<int>());
            SCCsVertices[SCCsVertices.size() - 1].insert(vertexOrder[i]);
        }
        else SCCsVertices[SCCsVertices.size() - 1].insert(vertexOrder[i]);
    }

    
    // output
    for (int i = 0; i < SCCsVertices.size(); i++) {
        std::cout << "SCC " << i << " : ";
        for (int j : SCCsVertices[i]) std::cout << j << ' ';
        std::cout << '\n';
    }
	
}

void DFS(int root, bool* state, int* finish, int* start, std::vector<std::vector<int>>& E, int& findOrder) {
    state[root] = 1;
    start[root] = findOrder++;
    for (int i = 0; i < E[root].size(); i++) {
        if (E[root][i] == 0) continue;
        if (state[i] == 0) DFS(i, state, finish, start, E, findOrder);
    }
    finish[root] = findOrder++;
}

void bubbleSort(int* arr, int* cmp_arr, int len) {
    for (int i = len; i > 0; i--) {
        for (int j = 0; j < i - 1; j++) {
            if (cmp_arr[arr[j]] > cmp_arr[arr[j + 1]]) {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}
```