κ°ν μ°κ²° μμ(Strongly Connected Component)
- λ μ μ μ λν΄ μλ°©ν₯μΌλ‘ μ΄λ κ°λ₯ν κ²½λ‘κ° λͺ¨λ μμ λ λ μ μ μ κ°μ κ° κ²°ν© μ»΄ν¬λνΈ(SCC)μ μνλ€. μ¦, κ·Έλνμ μ¬μ΄ν΄μμ κ°μ μ¬μ΄ν΄ λ΄μ μ‘΄μ¬νλ μ μ λ€μ κ°μ SCCμ μνλ€κ³ ν μ μλ€.
- λ°©ν₯ κ·Έλνμμλ§ μ μλλ€.
1. νμ μκ³ λ¦¬μ¦
1) κΈ°λ³Έ μ리
- κΉμ΄ μ°μ νμ
- λ°©ν₯ κ·Έλνμ μ μ λ€μ λ°©λ¬Έν ν λ°©λ¬Έν μ μ μ κ°μ μ ν΅ν΄ μμμμ λ°©λ¬Έλ μ μ μ λ°©λ¬Ένλ€λ©΄ SCCκ° μ‘΄μ¬νλ€κ³ νλ¨νλ€.
2) λ¬Έμ
https://www.acmicpc.net/problem/2150
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
vector<int> graph[10001];
vector<vector<int>> groups;
stack<int> group; // λ°©λ¬Έν λ
Έλλ€
bool grouped[10001]; // κ·Έλ£Ήν
int check[10001]; // λ°©λ¬Έ μμ
int num = 0; // λ°©λ¬Έ μμ μΈλ±μ€
int dfs(int index)
{
check[index] = ++num;
group.push(index);
int parent = check[index];
for (int i = 0; i < graph[index].size(); i++) {
int child = graph[index][i];
if (!check[child])
parent = min(parent, dfs(child));
else if (!grouped[child])
parent = min(parent, check[child]);
}
if (parent == check[index])
{
vector<int> v;
while (true) {
int t = group.top();
group.pop();
grouped[t] = true;
v.push_back(t);
if (t == index)
break;
}
sort(v.begin(), v.end());
groups.push_back(v);
}
return parent;
}
int main()
{
int V, E;
cin >> V >> E;
for (int i = 0; i < E; i++) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
}
for (int i = 1; i <= V; i++)
if (!check[i])
dfs(i);
sort(groups.begin(), groups.end());
cout << groups.size() << '\n';
for (int i = 0; i < groups.size(); i++) {
for (int j = 0; j < groups[i].size(); j++)
cout << groups[i][j] << ' ';
cout << "-1\n";
}
}
2. μ½μ¬λΌμ£Ό μκ³ λ¦¬μ¦
1) κΈ°λ³Έ μ리
- κΉμ΄ μ°μ νμ
- νμμ΄ μ’ λ£λλ μμλλ‘ μ μ μ μ€νμ μ μ₯νκ³ μ€νμ μλ¨λΆν° μλ°©ν₯ κ·Έλνλ₯Ό νκ³ DFSμ μννλ€.
2) λ¬Έμ
https://www.acmicpc.net/problem/2150
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> graph[10001], rev_graph[10001];
vector<vector<int>> groups(10001);
stack<int> nodes;
bool check[10001];
int groupsCount = 0;
void dfs(int index)
{
if (check[index])
return;
check[index] = true;
for (int i = 0; i < graph[index].size(); i++)
dfs(graph[index][i]);
nodes.push(index); // νμμ΄ μ’
λ£λλ©΄ μ μ μ μ₯
}
void rev_dfs(int index)
{
if (check[index])
return;
check[index] = true;
groups[groupsCount].push_back(index);
for (int i = 0; i < rev_graph[index].size(); i++)
rev_dfs(rev_graph[index][i]);
}
int main()
{
int V, E;
cin >> V >> E;
for (int i = 0; i < E; i++) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
rev_graph[b].push_back(a);
}
for (int i = 1; i <= V; i++)
if (!check[i])
dfs(i);
memset(check, false, sizeof(check));
while (!nodes.empty()) {
if (!check[nodes.top()]) {
rev_dfs(nodes.top());
sort(groups[groupsCount].begin(), groups[groupsCount].end());
groupsCount++;
}
nodes.pop();
}
sort(groups.begin(), groups.begin() + groupsCount);
cout << groupsCount << '\n';
for (int i = 0; i < groupsCount; i++) {
for (int j = 0; j < groups[i].size(); j++)
cout << groups[i][j] << ' ';
cout << "-1\n";
}
}