레야몬
[C++] 1766번 문제집 - 자료 구조, 그래프 이론, 우선순위 큐, 위상 정렬 본문
1. 문제
- 난이도 순서로 된 1~N번까지 총 N개의 문제로 되어 있는 문제를 풀려고 한다. 민오는 세 가지 조건에 따라 문제를 풀 순서를 정한다.
- N개의 문제를 모두 풀어야 한다.
- 먼저 푸는 것이 좋은 문제가 있는 문제는, 먼저 푸는 것이 좋은 문제를 반드시 먼저 풀어야 한다.
- 가능하면 쉬운 문제부터 푼다.
- 문제의 개수와 먼저 푸는 것이 좋은 문제에 대한 정보가 주어졌을 때, 주어진 조건에 맞는 민오가 풀 문제의 순서를 결정하시오.
<입력>
- - 1 - 문제의 수 \(N(1 \leq N \leq 32,000)\), 먼저 푸는 것이 좋은 문제에 대한 정보의 개수 \(M(1 \leq M \leq 100,000)\)
- - M개의 줄 - 두 정수의 순서쌍 A, B. A번 문제가 B번 문제보다 먼저 푸는 것이 좋다.
- 항상 문제를 모두 풀 수 있는 경우만 주어진다.
<출력>
- - 1 - 민오가 풀어야 하는 순서 출력
2. 재정의
- 가능하면 쉬운 문제를, 항상 먼저 푸는 것이 좋은 문제를 먼저 풀 때 문제 푸는 순서를 결정하시오.
3. 해결 방법
- 위상 정렬로 풀되 queue를 문제 번호에 따른 priority_queue로 바꿔서 푼다.
4. 실수한 점, 개선할 점
- X
<코드>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAX_N = 32001;
// <문제>
// 문제의 수 N, 먼저 푸는 것이 좋은 문제에 대한 정보의 수 M
int N, M;
// 문제 푸는 조건 용 단방향 그래프 adj
vector<int> adj[MAX_N];
// topology Sort
// 진입차수가 0인 문제 중 쉬운 문제 순으로 정렬된 우선순위 큐
priority_queue<int, vector<int>, greater<int>> pq;
// 진입차수 inDegree
int inDegree[MAX_N];
// 위상정렬 결과
vector<int> result;
void input() {
cin >> N >> M;
for(int i=0; i<M; i++) {
int A, B;
cin >> A >> B;
adj[A].push_back(B);
// 진입차수 설정하기
inDegree[B]++;
}
}
void topologySort() {
for(int i=1; i<=N; i++) {
// 진입차수가 0인 노드를 우선순위 큐에 저장
// 쉬운 문제부터 들어감
if(!inDegree[i])
pq.push(i);
}
// N번 정렬하면 위상 정렬이 끝
for(int i=0; i<N; i++) {
int x = pq.top();
pq.pop();
result.push_back(x);
for(auto next : adj[x]) {
// 연결된 노드의 진입차수가 0일 경우 우선순위 큐에 저장
if(!(--inDegree[next]))
pq.push(next);
}
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
input();
topologySort();
for(int i=0; i<N; i++)
cout << result[i] << ' ';
return 0;
}
<위상 정렬>
https://m.blog.naver.com/ndb796/221236874984
25. 위상 정렬(Topology Sort)
위상 정렬(Topology Sort)은 '순서가 정해져있는 작업'을 차례로 수행해야 할 때 그 순서를 ...
blog.naver.com
<priority queue>
[C++ STL] Priority_queue 사용법
본 글은 여러 PS 문제를 접하다 보면 우선순위 큐를 적극적으로 사용해야 되는 경우가 있는데 매번 구글링을 하게 되는 것 같아 우선순위 큐에 대한 기본적인 사용법뿐만 아니라 기본적인 자료
kbj96.tistory.com
<문제 바로가기>
https://www.acmicpc.net/problem/1766
1766번: 문제집
첫째 줄에 문제의 수 N(1 ≤ N ≤ 32,000)과 먼저 푸는 것이 좋은 문제에 대한 정보의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 둘째 줄부터 M개의 줄에 걸쳐 두 정수의 순서쌍 A,B가 빈칸을 사이에 두고 주
www.acmicpc.net
※현재 고등학교 등교 중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고 있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 13511번 트리와 쿼리 2 - 자료 구조, 트리, 최소 공통 조상, 희소 배열 (0) | 2022.12.20 |
---|---|
[C++] 3665번 최종 순위 - 그래프 이론, 위상 정렬 (0) | 2022.12.18 |
[C++] 1305번 광고 - KMP, 문자열 (0) | 2022.12.17 |
[C++] 5670번 휴대폰 자판 - 자료 구조, 문자열, 트리, 트라이 (0) | 2022.12.16 |
[C++] 1311번 할 일 정하기 1 - DP, 비트마스킹, 비트필드를 이용한 DP (0) | 2022.12.15 |
Comments