πŸ“ Computer Science/✏ Algorithm

[C++] μœ„μƒ μ •λ ¬(Topological Sort)

Blxxming 2021. 11. 17. 20:41

μœ„μƒ μ •λ ¬(Topological Sort)

μœ„μƒ 정렬은 μˆœμ„œκ°€ μ •ν•΄μ Έ μžˆλŠ” μž‘μ—…μ„ μ°¨λ‘€λ‘œ μˆ˜ν–‰ν•΄μ•Ό ν•  λ•Œ κ·Έ μˆœμ„œλ₯Ό κ²°μ •ν•΄μ£ΌκΈ° μœ„ν•œ μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

  • μ—¬λŸ¬ 개의 닡이 μ‘΄μž¬ν•  수 μžˆλ‹€.
  • DAG(Directed Acyclic Graph)μ—λ§Œ 적용이 κ°€λŠ₯ν•˜λ‹€.
  • μŠ€νƒκ³Ό 큐둜 κ΅¬ν˜„λœλ‹€.

 

κΈ°λ³Έ 원리

1 -> 2 -> 5 -> 3 -> 4 -> 6 -> 7

  • μ§„μž… μ°¨μˆ˜κ°€ 0인 정점을 큐에 μ‚½μž…ν•œλ‹€.
  • νμ—μ„œ μ›μ†Œλ₯Ό κΊΌλ‚΄ μ—°κ²°λœ λͺ¨λ“  간선을 제거 ν›„ μ§„μž… μ°¨μˆ˜κ°€ 0이 된 정점을 큐에 μ‚½μž…ν•œλ‹€.
  • 큐가 빌 λ•ŒκΉŒμ§€ 2번 과정을 λ°˜λ³΅ν•œλ‹€.
  • λͺ¨λ“  μ›μ†Œλ₯Ό λ°©λ¬Έν•˜κΈ° 전에 큐가 λΉˆλ‹€λ©΄ 사이클이 μ‘΄μž¬ν•˜λŠ” 것이고, λͺ¨λ“  μ›μ†Œλ₯Ό λ°©λ¬Έν–ˆλ‹€λ©΄ νμ—μ„œ κΊΌλ‚Έ μˆœμ„œκ°€ μœ„μƒ μ •λ ¬μ˜ 결과이닀.

 

문제

 

https://www.acmicpc.net/problem/1766

 

1766번: λ¬Έμ œμ§‘

첫째 쀄에 문제의 수 N(1 ≤ N ≤ 32,000)κ³Ό λ¨Όμ € ν‘ΈλŠ” 것이 쒋은 λ¬Έμ œμ— λŒ€ν•œ μ •λ³΄μ˜ 개수 M(1 ≤ M ≤ 100,000)이 μ£Όμ–΄μ§„λ‹€. λ‘˜μ§Έ 쀄뢀터 M개의 쀄에 걸쳐 두 μ •μˆ˜μ˜ μˆœμ„œμŒ A,Bκ°€ λΉˆμΉΈμ„ 사이에 두고 μ£Ό

www.acmicpc.net

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() 
{
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	int n, m;
	cin >> n >> m;

	vector<int> graph[32001];
	vector<int> degree(n + 1, 0);

	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
		degree[b]++;
	}

	priority_queue<int, vector<int>, greater<int>> pq;
	for (int i = 1; i <= n; i++)
		if (degree[i] == 0)
			pq.push(i);

	while (!pq.empty()) {
		int top = pq.top();
		cout << top << ' ';
		pq.pop();

		for (int i : graph[top]) {
			degree[i]--;
			if (degree[i] == 0)
				pq.push(i);
		}
	}
}

 

https://www.acmicpc.net/problem/3665

 

3665번: μ΅œμ’… μˆœμœ„

μ˜¬ν•΄ ACM-ICPC λŒ€μ „ 인터넷 μ˜ˆμ„ μ—λŠ” 총 n개의 νŒ€μ΄ μ°Έκ°€ν–ˆλ‹€. νŒ€μ€ 1λ²ˆλΆ€ν„° nλ²ˆκΉŒμ§€ λ²ˆν˜Έκ°€ 맀겨져 μžˆλ‹€. λ†€λžκ²Œλ„ μ˜¬ν•΄ μ°Έκ°€ν•˜λŠ” νŒ€μ€ μž‘λ…„μ— μ°Έκ°€ν–ˆλ˜ νŒ€κ³Ό λ™μΌν•˜λ‹€. μ˜¬ν•΄λŠ” 인터넷 μ˜ˆμ„  본뢀에

www.acmicpc.net

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int main()
{
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	int t;
	cin >> t;
	while (t--) {
		int n, m;
		cin >> n;

		int lastYearScore[501]{};
		for (int i = 0; i < n; i++)
			cin >> lastYearScore[i];

		bool graph[501][501]{};
		int degree[501]{};
		for (int i = 0; i < n; i++)
			for (int j = i + 1; j < n; j++) {
				graph[lastYearScore[i]][lastYearScore[j]] = true;
				degree[lastYearScore[j]]++;
			}

		cin >> m;
		while (m--) {
			int a, b;
			cin >> a >> b;

			if (graph[a][b]) {
				graph[b][a] = true;
				graph[a][b] = false;
				degree[a]++;
				degree[b]--;
			}
			else {
				graph[a][b] = true;
				graph[b][a] = false;
				degree[a]--;
				degree[b]++;
			}
		}

		queue<int> q;
		for (int i = 1; i <= n; i++)
			if (degree[i] == 0)
				q.push(i);

		vector<int> answer;
		while (!q.empty()) {
			int f = q.front();
			q.pop();
			answer.push_back(f);

			for (int i = 1; i <= n; i++) {
				if (graph[f][i]) {
					degree[i]--;
					if (degree[i] == 0)
						q.push(i);
				}
			}
		}

		if (answer.size() == n) {
			for (int j = 0; j < n; j++)
				cout << answer[j] << ' ';
			cout << endl;
		}
		else
			cout << "IMPOSSIBLE" << endl;
	}
}