# 利用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; } } } } ```