Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- vector
- OS
- 알고리즘
- 정석학술정보관
- 코딩
- 정석
- 브루트포스
- Stack
- 백준
- c++
- coding
- 컴공과
- 개발
- 북리뷰
- 구현
- 오에스
- 스택
- 너비우선탐색
- 컴퓨터공학과
- Operating System
- 컴공
- 코테
- 문제풀이
- 오퍼레이팅시스템
- 그래프
- bfs
- cs
- Computer science
- DP
- 자료구조
Archives
- Today
- Total
Little Jay
[C++] 백준 2150번 - Strongly Connected Component 본문
강연결요소는 DFS를 두번 실행해서 연결된 요소를 찾을 수 있다.
stack에 방문한 순서가 아닌 finished 되는 순서로 넣어야하기 때문에 이 점을 주의해서 풀면 될 것이다.
정렬을 빡세게 수행했는데 이렇게까지는 안해도 될 것 같다.
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
#define endl '\n'
#define vvi vector<vector<int>>
#define vi vector<int>
#define vb vector<bool>
int n, m;
int follower[50001];
void first_dfs(int start, vb& visited, vvi& adj, stack<int>& st) {
visited[start] = true;
for (auto next : adj[start])
if (!visited[next]) first_dfs(next, visited, adj, st);
st.push(start);
}
void second_dfs(int start, int leader, vb& visited, vvi& adj, vi& component) {
visited[start] = true;
component.push_back(start);
for (auto next : adj[start]) {
if (!visited[next]) second_dfs(next, leader, visited, adj, component);
}
}
vvi transpose(int vertexNum, vvi adj) {
vvi transpose(vertexNum);
for (int i = 1; i < vertexNum; i++) {
for (auto next : adj[i])
transpose[next].push_back(i);
}
return transpose;
}
bool comp(vi& a, vi& b) {
if (a[0] == b[0]) return a[1] < b[1];
return (a[0] > b[0]);
}
vvi dfs_order(int vertexNum, vvi& adj) {
vvi temp;
temp.resize(vertexNum);
for (int i = 1; i < vertexNum; i++) {
temp[i].push_back(follower[i]); temp[i].push_back(i);
}
sort(temp.begin() + 1, temp.end(), comp);
return temp;
}
vvi solve(int vertexNum, vvi adj) {
vb visited(vertexNum, false);
stack<int> st;
vvi tranposed = transpose(vertexNum, adj);
for (int i = 1; i < vertexNum; i++) {
sort(adj[i].begin(), adj[i].end());
}
vvi order = dfs_order(vertexNum, adj);
for (int i = 1; i < vertexNum; i++) {
if (!visited[order[i][1]]) first_dfs(order[i][1], visited, adj, st);
}
for (int i = 1; i < vertexNum; i++) visited[i] = false;
vvi scc;
while (!st.empty()) {
int current = st.top(); st.pop();
if (!visited[current]) {
vector<int> component;
second_dfs(current, current, visited, tranposed, component);
scc.push_back(component);
}
}
return scc;
}
bool scc_cmp(vi& a, vi& b) {
if (a[0] > b[0]) return false;
else return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
vvi v;
v.resize(n + 1);
for (int i = 0; i < m; i++) {
int a, b; cin >> a >> b;
v[a].push_back(b);
follower[b]++;
}
vvi my_scc = solve(n + 1, v);
for (int i = 0; i < my_scc.size(); i++) {
sort(my_scc[i].begin(), my_scc[i].end());
}
sort(my_scc.begin(), my_scc.end(), scc_cmp);
cout << my_scc.size() << endl;
for (int i = 0; i < my_scc.size(); i++) {
for (int child : my_scc[i])
cout << child << " ";
cout << -1 << endl;
}
cout << endl;
return 0;
}
'알고리즘 > BOJ' 카테고리의 다른 글
[C++] 백준 3613번 - Java vs C++ (0) | 2022.07.01 |
---|---|
[C++] 백준 11049번 - 행렬 곱셈 순서 (0) | 2022.07.01 |
[C++] 백준 11404번 - 플로이드 (0) | 2022.06.04 |
[C++] 백준 4358번 - 생태학 (0) | 2022.06.02 |
[C++] 백준 2018번 - 수들의 합 5 (0) | 2022.05.23 |
Comments