1766번: 문제집
첫째 줄에 문제의 수 N(1 ≤ N ≤ 32,000)과 먼저 푸는 것이 좋은 문제에 대한 정보의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 둘째 줄부터 M개의 줄에 걸쳐 두 정수의 순서쌍 A,B가 빈칸을 사이에 두고 주
www.acmicpc.net
어떤 문제를 풀기 위해서 먼저 풀어야 하는 문제가 있다고 한다. 이때 어떤 문제는 먼저 풀어야 하는 문제에 의존적이라고 할 수 있다.
이 문제처럼 정점끼리 서로 의존성이 존재하는 경우 위상정렬을 통해 올바른 순서를 찾을 수 있다.
이전까지는 DFS를 수행한 결과를 역순으로 출력하여 위상정렬을 수행하는 방법만 알고 있었는데,
이 문제를 통해 들어오는 간선의 개수(in degree)를 이용하여 위상정렬을 수행하는 방법을 새롭게 알게 되었다.
ps// 아래 블로그를 참고하여 풀었는데, 위상정렬에 대한 설명이 잘 되어있는 것 같다.
Topological Sort(위상 정렬)
DAG에서 방향성을 거스르지 않게 정점들을 나열하는 알고리즘을 Topological sort(위상 정렬)이라 합니다. DAG란 Directed Acyclic Graph의 줄임말로 직역하자면 사이클이없는 방향(유향) 그래프 정도가 될
jason9319.tistory.com
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
vector<int> adj[32001];
int indegree[32001];
vector<int> topologicalSort(int N) {
priority_queue<int> pq;
for (int i = 1; i <= N; i++)
if (indegree[i] == 0)
pq.push(-i);
vector<int> order;
while (!pq.empty()) {
int here = -pq.top();
pq.pop();
order.push_back(here);
for (auto x : adj[here]) {
indegree[x]--;
if (indegree[x] == 0)
pq.push(-x);
}
}
return order;
}
int main(void) {
int N, M;
cin >> N >> M;
for (int i = 0; i < M; i++) {
int A, B;
cin >> A >> B;
adj[A].push_back(B);
indegree[B]++;
}
vector<int> result = topologicalSort(N);
for (auto x : result)
cout << x << ' ';
return 0;
}

'알고리즘 > BOJ' 카테고리의 다른 글
백준 1991번: 트리 순회 (0) | 2021.04.23 |
---|---|
백준 7425번: Flip Game (0) | 2021.04.22 |
백준 17142번: 연구소 3 (0) | 2021.04.21 |
백준 16235번: 나무 재테크 (0) | 2021.01.16 |
백준 14890번: 경사로 (0) | 2021.01.07 |