🍞 Problem Solving/Baekjoon

[백준] 1613 역사 c++

박빵이 2022. 9. 5. 00:09

풀이과정

예전에 풀었던 플로이드 와샬의 백준 키 순서와 비슷한 문제였다.  
키 순서 문제 참고하기 

 

2458번: 키 순서

1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여

www.acmicpc.net


처음에 입력을 받자마자 num[x][y] = 1, num[y][x] = 2 값을 넣어주는데  
1은 앞에 있는 번호의 사건이 먼저 일어났다는 뜻이고,  
2는 뒤에 있는 번호의 사건이 먼저 일어났다는 뜻이다.

플로이드 와샬 함수의 num[i][k] == 1 && num[k][j] == 1 부분은 경유지를 거치면서 가는 길이 있다는 뜻이고, 사건의 전후 관계를 알 수 있다는 뜻이다. 그러므로, 시작 지점과 도착 지점에 1과 2를 넣어준다.  
만약 num[1][4]라면 k = 2, i = 1, j = 4이므로 num[1][4] = 1, num[4][1] = 2를 넣어줌으로써 1은 4보다 먼저 일어났고, 4는 1보다 늦게 일어났다는 것을 알 수 있다

 

=> 플로이드 와샬 수행한 후 

 

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

int n, k, x, y, s, xs, ys;
int num[401][401];
const int INF = 1e9;

void floyd() {
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				if (num[i][k] == 1 && num[k][j] == 1) {
					num[i][j] = 1; // i가 j보다 먼저 일어난 사건
					num[j][i] = 2; // j가 i보다 먼저 일어난 사건
				}
			}
		}
	}
}

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

	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (i != j) num[i][j] = INF;
		}
	}
	for (int i = 0; i < k; i++) {
		cin >> x >> y;
		num[x][y] = 1; // x가 y보다 먼저 일어난 사건
		num[y][x] = 2; // y가 x보다 먼저 일어난 사건
	}
	floyd();

	cin >> s;
	for (int i = 0; i < s; i++) {
		cin >> xs >> ys;
		if (num[xs][ys] == 1) cout << -1;
		else if (num[xs][ys] == 2) cout << 1;
		else cout << 0; // num[xs][ys] == INF
		cout << "\n";
	}
}