성우리뷰

우선순위큐 공부

두원공대88학번뚜뚜 2021. 1. 5. 02:41
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;
//각 정점간위 순서를 나타낼 정점들의 배열
vector <vector <int>> v;
//우선순위 큐
priority_queue< int, vector<int>, greater<int> > pq;
const int Max = 32e3;

int main(void) {

	int N, M;
	int from, to;
	int degree[Max+1] = { 0 };

	cin >> N >> M;
	v.resize(N + 1);

	for (int i = 0; i < M; i++) {
		cin >> from >> to;
		v[from].push_back(to);
		degree[to]++;
	}

	//degree가 0인 것들을, 순서대로 먼저 우선순위 큐에 삽입처리
	for (int i = 1; i <= N; i++) {
		if (!degree[i])
			pq.push(i);
	}

	int now;
	while (!pq.empty()) {
		now = pq.top();
		pq.pop();
		printf("%d ", now);
		//총 v[now]와 관련된 정점(now가 선행하는)의 개수만큼 for문 진행
		//이것과 관련된 것들의 degree를 1씩 없애고, 이를 우선순위 큐에 삽입
		for (auto next : v[now])
			if (--degree[next] == 0)
				pq.push(next);
	}
	
	return 0;
}

priority_queue<int, vector<int>, greater<int>> v 등으로 우선순위 큐의 대체가 가능

각 정점과 수반되는 정점을 만들 때마다, vector<vector<int>>로 정의된 2중벡터에서 vector<from>의 요소에 to를 하나 추가한다. 이를 반복

 

이후엔, degree를 토대로, 0이 아닌 것들은 수반되는 것 없이 처리되는 것들이므로, 죄다 삽입한다

이후엔, 이것들을 처리하면서, 이것과 수반되는 것이 있다면(이는, v[now]의 요소가 0인지 아닌지의 요소로 판별 가능하다) 만약 0이라면 이는 now를 선행으로 하는 정점이면서 동시에 이후에 선행해야 할 요소가 없다는 뜻이기도 하다. 따라서 즉시 큐에 삽입한다. 이때, pq에 삽입하면 알아서 우선순위를 토대로 정렬이 된다. c++의 위대함!

 

따라서, 이를 큐가 완전히 빌 때까지 반복하면 된다.