[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ๊ฐํ ์ฐ๊ฒฐ ์์(Strongly Connected Component)
Strongly Connected Component
๊ฐํ ์ฐ๊ฒฐ ์์(SCC)
๋ผ๊ณ ๋ ํ๋ Strongly Connected Component ๋ ๋ฐฉํฅ ๊ทธ๋ํ์์ ๋ค์๊ณผ ๊ฐ์ ์กฐ๊ฑด์ด ์ฑ๋ฆฝํ๋ ์ ์ ๋ค์ ์งํฉ์ด๋ค.
- SCC ๋ด์ ์๋ ์ด๋ค ๋ ์ ์ ์ ๋ํ ๊ฒฝ๋ก๊ฐ ํญ์ ์กด์ฌํ๋ค. ์ฆ, ์ฌ์ดํด์ด ์กด์ฌํ๋ค.
- ์๋ก ๋ค๋ฅธ SCC์ ์ํ๋ ๋ ์ ์ ์ ์๋ก ์๋ฐฉํฅ์ผ๋ก ์ฐ๊ฒฐ๋ ์ ์๋ค. ์ฆ, SCC ๊ฐ์๋ ์ฌ์ดํด์ด ์กด์ฌํ ์ ์๋ค.
์์ ๊ฐ์ ๊ทธ๋ํ์์ {A, B, C}, {C, D}, {F, G}, {H} ๋ค ๊ฐ์ Strongly Connected Component ๊ฐ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
Algorithm
๊ทธ๋ํ์์ Strongly Connected Graph๋ฅผ ์ฐพ๋ ๊ฒ์ ์ฐ๋ฆฌ๊ฐ ๋์ผ๋ก ํ๋ฒ์ ์ ์ ์๋ ๊ฒ๊ณผ๋ ์กฐ๊ธ ๋ค๋ฅด๋ค. ๋ง์ฝ ์ ์ ์ด ๊ต์ฅํ ๋ง์ ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ก๋ค๋ฉด ์ด๋ค ๋ฐฉ๋ฒ์ผ๋ก ์ปดํจํฐ๊ฐ SCC ๋ฅผ ๊ตฌ๋ณํ ์ ์๊ฒ ํ ์ ์์๊น?
์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๊ฒ ์ง๋ง, ์ ์์ ์ธ ๋ฐฉ๋ฒ์ DFS๋ฅผ ํ์ฉํ๋ ๊ฒ์ด๋ค.
Applying DFS
DFS๋ฅผ ์ด์ฉํด์ SCC๋ฅผ ์ฐพ์ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์์ ์ ๊ฑฐ์น๋ค.
- DFS ๋ก ๊ฐ ์ ์ ์
finish time
์ ๊ธฐ๋กํ๋ค. - ํ์ฌ ๊ทธ๋ํ๋ฅผ
Transpose
ํ๋ค. ์ฆ, ๊ฐ Edge์ ๋ฐฉํฅ์ ๋ฐ๋๋ก ์ทจํ๋ค. - Transposeํ ๊ทธ๋ํ์ ๋ํด์ DFS๋ฅผ ์ ์ฉํ์ฌ ๊ทธ๋ํ ๋ด์ ์๋ ๋ชจ๋ ํธ๋ฆฌ๋ฅผ ์ฐพ์์ค๋ค. ์ด๋, ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ ์์ํ ๋ฃจํธ ๋
ธ๋๋
finish time์ด ๊ฐ์ฅ ๋ฆ์ ์ ์ ์์ผ๋ก ์งํ
์ด ๋๋ค.
Proof
์๊ณ ๋ฆฌ์ฆ์ ๋ฌด์ฒ์ด๋ ๊ฐ๋จํด๋ณด์ด๋๋ฐ, ์ด๋ป๊ฒ ์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก SCC๋ฅผ ์ฐพ๋ ๊ฒ์ด ๊ฐ๋ฅํ ๊น?
Lemma 1
์ด๋ค ๋ SCC X ์ Y๊ฐ ์๋ค๊ณ ํ์. ๋ง์ฝ X์ ์ํ ์ ์ ์ธ u ๊ฐ Y์ ์ํ๋ ์ ์ v์ ์ผ๋ฐฉํฅ์ผ๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๋ฉด, v๋ A์ ์ํ๋ ๋ค๋ฅธ ์ด๋ค ์ ์ ๊ณผ๋ ์ฐ๊ฒฐ๋ ์ ์๋ค. ์๋ํ๋ฉด ๋ง์ฝ v๊ฐ X์ ์ํ ์ ์ ์ค ํ๋๋ฅผ ๊ฐ๋ฅดํค๊ฒ ๋๋ฉด ๋ SCC ์ฌ์ด์๋ ์ฌ์ดํด์ด ์๊ธฐ๊ฒ ๋๊ณ , SCC์ ์ฑ์ง์ ์๊ฒ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ๊ฐ์ ๋ SCC๋ก ์ด๋ฃจ์ด์ง ๊ทธ๋ํ๊ฐ ์๋ค๊ณ ํ ๋, ์ด๋ก์ SCC์ ์ํ๋ B ๋ ธ๋๊ฐ ๋ ธ๋์ SCC์ ์ํ๋ F๋ฅผ ๊ฐ๋ฅดํค๊ณ ์๋ ์ํฉ์์ F๊ฐ B๋ฅผ ๊ฐ๋ฅดํค๋ edge๊ฐ ์๊ธฐ๊ฒ ๋๋ฉด ์ ๋ SCC ๋ชจ๋ ๋ ์ด์ SCC๊ฐ ์๋๊ฒ ๋๋ค.
Lemma 2
๋๋ถ์ด์, ๋ง์ฝ ์ด๋ค ๋ SCC๋ฅผ ์ฐ๊ฒฐํ๋ edge ๊ฐ ์๋ค๊ณ ํ์ ๋, edge์ ์์์ ์ ์๋ SCC์ ์ ์ ๋ค ์ค ๊ฐ์ฅ ๋ฆ์ finsh time์ edge๊ฐ ๊ฐ๋ฅดํค๋ SCC์ finish time ๋ณด๋ค ๋นจ๋ผ์ผ ํ๋ค. ์ฌ๊ธฐ์ finish time์ ํ SCC์ ์๋ ์ ์ ์ค ํ์์ด ์์ ํ ๋๋๋๋ฐ ๊ฐ์ฅ ์ค๋ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ๋ ธ๋๋ฅผ ์๋ฏธํ๋ค. ์ด ์ ๋ฆฌ๋ ๋จ์ํ๊ณ ๋น์ฐํ ๊ฒ์ธ๋ฐ, ํ SCC์์ ๋ค์ SCC๋ก ๋์ด๊ฐ๋ ๊ธธ์ด ํญ์ ํ ๋ฐฉํฅ์ด์ด์ผ ํ๋ค๋ Lemma 1์ ์ ๋ฆฌ์ ์ํด ์ด๋ค SCC๋ ํญ์ ๊ทธ SCC๊ฐ ๊ฐ๋ฅดํค๋ SCC ์ด์ ์ ํ์๋ ์ ๋ฐ์ ์๋ค.
์ด ๊ทธ๋ฆผ์์๋ B์์ F๋ก ์ฐ๊ฒฐ๋๋ edge๊ฐ ์ผ๋ฐฉํฅ์ด๊ธฐ ๋๋ฌธ์ {A, B, C}๋ก ์ด๋ฃจ์ด์ง SCC๊ฐ {F, G} ๋ก ์ด๋ฃจ์ด์ง SCC ๋ณด๋ค ํญ์ ๋จผ์ ํ์๋๋ค.
Corollary
์ด์ ๊ฐ edge์ ์ญ๋ฐฉํฅ์ ์ทจํด์ transpose ๋ ๊ทธ๋ํ๋ก ๋ณํ์์ผ๋ณด์. ์ด๋ ์ฐ๋ฆฌ๋ ์์ ์ ๋ฆฌ์ ์ํด์ ๋ ๋ค๋ฅธ ์ ๋ฆฌ๋ฅผ ๋์ถํด ๋ผ ์ ์๋ค. Lemma 2 ์์ ์ ๋ฆฌํ๋ ๋ฐ์ ๋ฐ๋ฅด๋ฉด ์ด๋ค ๋ SCC A ์ B๊ฐ ์ฐ๊ฒฐ๋์ด ์๋ค๊ณ ํ์ ๋, A์์ B ๋ฐฉํฅ์ผ๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๋ฉด, SCC A์ ๋๋๋ ์๊ฐ์ด ํญ์ SCC B ๊ฐ ๋๋๋ ์๊ฐ๋ณด๋ค ์๋ค. ๋ฐ๋ผ์ ๊ทธ๋ํ์ ์ญ๋ฐฉํฅ์ ์ทจํ๊ฒ ๋๋ฉด, ์ด edge๋ ๋ฐ๋๋ฐฉํฅ์ ๊ฐ๋ฅดํค๊ฒ ๋๊ณ ์ด์ SCC B๊ฐ ๋๋๋ ์๊ฐ์ด SCC A๊ฐ ๋๋๋ ์๊ฐ๋ณด๋ค ์์์ง ๊ฒ์ด๋ค.
์ด ๊ทธ๋ฆผ์์๋ ์ฝ๊ฒ ํ์ธํ ์ ์๋ค. {F, G} ๋ก ์ด๋ฃจ์ด์ง SCC์ ํ์์ด ๋๋์ผ {A, B, E} ๋ก ์ด๋ฃจ์ด์ง SCC๋ก ์ด๋ํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ์ ๋ฆฌ์ ์ด์ด Lemma 1์ ์ํด {A, B, E} ๋ก ์ด๋ฃจ์ด์ง SCC๋ก๋ถํฐ {F, G} ๋ก ์ด๋ฃจ์ด์ง SCC๋ก ์ฐ๊ฒฐ๋๋ edge๊ฐ ์์ ์ ์๋ค๋ ๊ฒ ๋ํ ์ฆ๋ช ๋๋ค.
Implementation
[๋ฐฑ์ค ์๊ณ ๋ฆฌ์ฆ] 2150๋ฒ: Strongly Connected Component
๊ณต๋ถํ ๋ด์ฉ์ ํ ๋๋ก ์ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์๋ค. ์๊ฐ๋ณด๋ค ์ฝ์ง ์์์ ๊ตฌ๊ธ๋ง์ผ๋ก ๋ก์ง์ ๋ ๊ณต๋ถํ๋ฉด์ ํ์๋ค. SCC์์ ์ค์ํ ์ ์ ๋๋์๊ฐ ์์๋๋ก ์ญ๋ฐฉํฅ ํ์์ ์งํํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ Topology Sort ๋ฅผ ๊ตฌํํ ๋ ์ผ๋ ์ ๋ต์ ๊ทธ๋๋ก ์ฌ์ฉํด์ ๋๋๋ ์๊ฐ์ ๋ฐ๋ผ ๋ ธ๋๋ค์ ์คํ์ ์์๋๊ณ , ์ญ๋ฐฉํฅ์ผ๋ก ํ์ํ ๋๋ ์คํ์ ์๋ ๋ ธ๋๋ค์ ํ๋์ฉ ๊บผ๋ด์ ๋ฃจํธ๋ ธ๋๋ก ์ผ๋ ๊ฒ์ด ๊ฐ์ฅ ๊ตฌํํ๊ธฐ์ ๊ฐํธํ๋ค. ์ญ๋ฐฉํฅ์ ๋ํ ํํ์ ์ต์ด์ ์ฌ์ฉ์์๊ฒ ์ ๋ ฅ์ ๋ฐ์ ๋, ์ธ์ ๋ ธ๋๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๋ฉด์ ์ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก์ ๋ฆฌ์คํธ๋ ๊ฐ์ด ์์ฑํด์ฃผ๋ฉด ๋๋ค.
#include <cstdio>
#include <queue>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
bool visited[10001];
vector<vector<int>> result;
vector<vector<int>> adj;
vector<vector<int>> adjTrans;
stack<int>stk;
void dfs(int root){
visited[root] = true;
for (int i = 0 ; i < adj[root].size() ; i++){
if (!visited[adj[root][i]]){
dfs(adj[root][i]);
}
}
stk.push(root);
}
void scc(int root){
visited[root] = true;
for (int i = 0 ; i < adjTrans[root].size() ; i++){
if (!visited[adjTrans[root][i]]){
scc(adjTrans[root][i]);
result.back().push_back(adjTrans[root][i]);
}
}
}
int main (){
int V, E;
scanf("%d %d", &V, &E);
adj.resize(V+1);
adjTrans.resize(V+1);
for (int i = 0 ; i < E ; i++){
int a, b;
scanf("%d %d", &a, &b);
adj[a].push_back(b);
adjTrans[b].push_back(a);
}
for (int i = 1 ; i <= V ; i++){
if(!visited[i]){
dfs(i);
}
}
for (int i = 0 ; i <=V ; i++) visited[i] = false;
while(!stk.empty()){
if (!visited[stk.top()]){
vector<int> temp(1);
temp[0] = stk.top();
result.push_back(temp);
scc(stk.top());
}
stk.pop();
}
printf("%lu\n", result.size());
for (int i = 0 ; i < result.size() ; i++){
sort(result[i].begin(), result[i].end());
}
sort(result.begin(), result.end());
for (auto v : result){
for (auto i : v){
printf("%d ", i);
}
printf("-1\n");
}
}
'๐ฎ ์จ-์์ค > ๐ ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ์ต์ ์ ์ฅ ํธ๋ฆฌ(MST) (1) | 2021.07.18 |
---|---|
[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ์๊ณ ๊ฒฝ๋ก(Critical Path) (0) | 2021.07.18 |
[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ๊น์ด ์ฐ์ ํ์(DFS) (0) | 2021.07.18 |
[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ๋๋น ์ฐ์ ํ์(BFS) (0) | 2021.07.18 |
[์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ] ๋ฐฐ๋ญ ๋ฌธ์ (Knapsack Problem) (7) | 2021.07.17 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote