Uknow's Lab.
article thumbnail

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

 

1613번: 역사

첫째 줄에 첫 줄에 사건의 개수 n(400 이하의 자연수)과 알고 있는 사건의 전후 관계의 개수 k(50,000 이하의 자연수)가 주어진다. 다음 k줄에는 전후 관계를 알고 있는 두 사건의 번호가 주어진다.

www.acmicpc.net

 

난이도 : 골드 3
태그 : 그래프 이론, 플로이드-워셜

 

 

1. 설명

플로이드 워셜 알고리즘을 응용하여 풀 수 있을 것 같습니다.

플로이드 워셜 알고리즘을 잘 모르겠다면, 아래 포스팅을 참고해주세요.

https://uknowblog.tistory.com/39

 

[백준 11404번][Kotlin] 플로이드

https://www.acmicpc.net/problem/11404 11404번: 플로이드 첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다.

uknowblog.tistory.com

 

 

플로이드 워셜 알고리즘은 최단경로를 구하는 알고리즘이지만,

순서를 구할 때에도 응용할 수 있습니다.

 

 

 

2. 소스코드

<kotlin />
import java.util.* fun main() = with(System.`in`.bufferedReader()) { val (n, k) = readLine().split(" ").map { it.toInt() } val arr = Array(n + 1) { Array(n + 1) { 987654321 } } repeat(k) { val st = StringTokenizer(readLine()) val from = st.nextToken().toInt() val to = st.nextToken().toInt() arr[from][to] = 1 } for (k in 1..n) { for (i in 1..n) { for (j in 1..n) { if (arr[i][j] > arr[i][k] + arr[k][j]) { arr[i][j] = arr[i][k] + arr[k][j] } } } } val sb = StringBuilder() repeat(readLine().toInt()) { val st = StringTokenizer(readLine()) val from = st.nextToken().toInt() val to = st.nextToken().toInt() if (arr[from][to] == arr[to][from]) sb.append("0") else if (arr[from][to] > arr[to][from]) sb.append("1") else sb.append("-1") sb.append("\n") } print(sb) }

 

일반적인 플로이드 워셜 알고리즘과 같으나,

a와 b의 순서관계가 주어진다면 arr[a][b]를 1로 만들어줍니다.

이후, 플로이드 워셜 알고리즘을 적용시키고,

플로이드 워셜이 끝나면

arr[a][b]와 arr[b][a]의 값을 비교합니다.

arr[a][b]가 arr[b][a]보다 크다면,  b의 사건이 먼저 일어난 것입니다. 따라서 1을,

arr[b][a]가 arr[a][b]보다 크다면, a의 사건이 먼저 일어난 것이므로 -1을,

arr[a][b]와 arr[b][a]가 같다면 순서를 가릴 수 없으므로 0을 출력합니다.

 

 

3. 후기

그래프는 언제 해도 재밌습니다.

 

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.