본문 바로가기

알고리즘/BOJ

1766번

1766번 - 문제집


위상정렬과 우선순위큐를 이용한 문제였다.


나는 우선 순위 큐를 몰라서 따로 구글에서 검색해서 알아봤다. 


가장 핵심은 디폴트 값이 가장 큰 값을 가장 우선 순위로 두는 max heap 이라는 점이었다.


사실 이 문제는 가장 작은 값을 우선 순위로 둬야하는데, 그 테크닉을 -1을 곱해주는 방법을 통해서 극복했다.(물론 다른 분들꺼 답습)




##문제 풀면서의 고민##


우선 순위큐를 이용하면 중간에 정점들이 뒤섞여서 순서가 바뀌지 않을까? 하는 걱정이었다.


백준 SLACK 을 통해서 질문을 하니 갓분들께서 답변을 주셨다.


큐 안에 들어있는 값들은 indegree 값이 0이기 때문에 언제 빼내도 상관없고, 그렇기 때문에 섞을 수 있다고 했다.


나는 indegree 가 0이어도 뭔가 섞이지 않을까 머리가 속 시원하지는 않았다. 그런데 여러 위상 정렬 예시를 보면서 내가 가진 의문을 보니


약간은 의문이 풀리면서, 이해가 가는 것 같다. (사실 아직 뻥 뚤린 느낌은 아닌데..여러 사례에서 유추해보니 그렇다)


indegree 가 0이라는 것은 결국 어느 노드한테도 영향을 받지 않는 다는 뜻이니까....아무튼


위상 정렬 문제랑 똑같은 우선 순위 큐만 쓰면 되는 문제였다.


<정답 코드>


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int N, M;
int indegree[32001];
vector<vector<int>> v;
int main()
{
    cin >> N >> M;
    
    v.resize(N + 1);
    for (int i = 0; i < M; i++)
    {
        int a, b;
        cin >> a >> b;
        v[a].push_back(b);
        indegree[b]++;
    }
 
    priority_queue<int> pq;
 
    for (int i = 1; i <= N; i++)
    {
        if (indegree[i] == 0)
        {
            pq.push(-i);
        }
    }
 
    while (!pq.empty())
    {
        int now = -pq.top();
        pq.pop();
        printf("%d ", now);
 
        for (int i = 0; i < v[now].size(); i++)
        {
            int next = v[now][i];
            indegree[next]--;
 
            if (indegree[next] == 0)
            {
                pq.push(-next);
            }
        }
    }
 
 
    return 0;
}
cs


반응형

'알고리즘 > BOJ' 카테고리의 다른 글

2089번  (0) 2017.12.08
1212번  (0) 2017.12.08
11403번  (0) 2017.12.05
2252번  (0) 2017.12.05
11723번  (0) 2017.12.05