1613번: 역사
첫째 줄에 첫 줄에 사건의 개수 n(400 이하의 자연수)과 알고 있는 사건의 전후 관계의 개수 k(50,000 이하의 자연수)가 주어진다. 다음 k줄에는 전후 관계를 알고 있는 두 사건의 번호가 주어진다.
www.acmicpc.net
문제
역사, 그 중에서도 한국사에 해박한 세준이는 많은 역사적 사건들의 전후 관계를 잘 알고 있다. 즉, 임진왜란이 병자호란보다 먼저 일어났으며, 무오사화가 기묘사화보다 먼저 일어났다는 등의 지식을 알고 있는 것이다.
세준이가 알고 있는 일부 사건들의 전후 관계들이 주어질 때, 주어진 사건들의 전후 관계도 알 수 있을까? 이를 해결하는 프로그램을 작성해 보도록 하자.
입력
첫째 줄에 첫 줄에 사건의 개수 n(400 이하의 자연수)과 알고 있는 사건의 전후 관계의 개수 k(50,000 이하의 자연수)가 주어진다. 다음 k줄에는 전후 관계를 알고 있는 두 사건의 번호가 주어진다. 이는 앞에 있는 번호의 사건이 뒤에 있는 번호의 사건보다 먼저 일어났음을 의미한다. 물론 사건의 전후 관계가 모순인 경우는 없다. 다음에는 사건의 전후 관계를 알고 싶은 사건 쌍의 수 s(50,000 이하의 자연수)이 주어진다. 다음 s줄에는 각각 서로 다른 두 사건의 번호가 주어진다. 사건의 번호는 1보다 크거나 같고, N보다 작거나 같은 자연수이다.
출력
s줄에 걸쳐 물음에 답한다. 각 줄에 만일 앞에 있는 번호의 사건이 먼저 일어났으면 -1, 뒤에 있는 번호의 사건이 먼저 일어났으면 1, 어떤지 모르면(유추할 수 없으면) 0을 출력한다.
코드
import sys
input = sys.stdin.readline
INF = int(1e9)
n, k = map(int, input().split())
dist = [[INF] * (n+1) for _ in range(n+1)]
for _ in range(k):
a, b = map(int, input().split())
dist[a][b] = 1
# 플로이드 워셜
for k in range(1, n+1):
for i in range(1, n+1):
for j in range(1, n+1):
if dist[i][j] > (dist[i][k] + dist[k][j]):
dist[i][j] = (dist[i][k] + dist[k][j])
s = int(input())
for _ in range(s):
a, b = map(int, input().split())
if dist[a][b] != INF:
print(-1)
elif dist[b][a] != INF:
print(1)
else:
print(0)
Python3로는 시간초과...PyPy3로는 통과한다.
플로이드 워셜 알고리즘을 사용하여 모든 정점의 최단거리를 계산하여 dist 2차원 배열에 저장한다. a에서 b로 가는 경로가 존재하는지 확인하고 싶다면 dist[a][b]의 값이 초기값으로 설정한 INF가 아닌지 확인해보면 된다.
'문제풀이 > 최단경로' 카테고리의 다른 글
[Python/파이썬] 백준 21940번 가운데에서 만나기 (1) | 2023.10.23 |
---|---|
[Python/파이썬] 백준 16118번 달빛 여우 (1) | 2023.08.23 |
[Python/파이썬] 백준 11657번 타임머신 (0) | 2023.05.16 |
[Python/파이썬] 백준 10159번 저울 (1) | 2023.05.15 |
[Python/파이썬] 백준 1956번 운동 (1) | 2023.05.14 |
1613번: 역사
첫째 줄에 첫 줄에 사건의 개수 n(400 이하의 자연수)과 알고 있는 사건의 전후 관계의 개수 k(50,000 이하의 자연수)가 주어진다. 다음 k줄에는 전후 관계를 알고 있는 두 사건의 번호가 주어진다.
www.acmicpc.net
문제
역사, 그 중에서도 한국사에 해박한 세준이는 많은 역사적 사건들의 전후 관계를 잘 알고 있다. 즉, 임진왜란이 병자호란보다 먼저 일어났으며, 무오사화가 기묘사화보다 먼저 일어났다는 등의 지식을 알고 있는 것이다.
세준이가 알고 있는 일부 사건들의 전후 관계들이 주어질 때, 주어진 사건들의 전후 관계도 알 수 있을까? 이를 해결하는 프로그램을 작성해 보도록 하자.
입력
첫째 줄에 첫 줄에 사건의 개수 n(400 이하의 자연수)과 알고 있는 사건의 전후 관계의 개수 k(50,000 이하의 자연수)가 주어진다. 다음 k줄에는 전후 관계를 알고 있는 두 사건의 번호가 주어진다. 이는 앞에 있는 번호의 사건이 뒤에 있는 번호의 사건보다 먼저 일어났음을 의미한다. 물론 사건의 전후 관계가 모순인 경우는 없다. 다음에는 사건의 전후 관계를 알고 싶은 사건 쌍의 수 s(50,000 이하의 자연수)이 주어진다. 다음 s줄에는 각각 서로 다른 두 사건의 번호가 주어진다. 사건의 번호는 1보다 크거나 같고, N보다 작거나 같은 자연수이다.
출력
s줄에 걸쳐 물음에 답한다. 각 줄에 만일 앞에 있는 번호의 사건이 먼저 일어났으면 -1, 뒤에 있는 번호의 사건이 먼저 일어났으면 1, 어떤지 모르면(유추할 수 없으면) 0을 출력한다.
코드
import sys input = sys.stdin.readline INF = int(1e9) n, k = map(int, input().split()) dist = [[INF] * (n+1) for _ in range(n+1)] for _ in range(k): a, b = map(int, input().split()) dist[a][b] = 1 # 플로이드 워셜 for k in range(1, n+1): for i in range(1, n+1): for j in range(1, n+1): if dist[i][j] > (dist[i][k] + dist[k][j]): dist[i][j] = (dist[i][k] + dist[k][j]) s = int(input()) for _ in range(s): a, b = map(int, input().split()) if dist[a][b] != INF: print(-1) elif dist[b][a] != INF: print(1) else: print(0)
Python3로는 시간초과...PyPy3로는 통과한다.
플로이드 워셜 알고리즘을 사용하여 모든 정점의 최단거리를 계산하여 dist 2차원 배열에 저장한다. a에서 b로 가는 경로가 존재하는지 확인하고 싶다면 dist[a][b]의 값이 초기값으로 설정한 INF가 아닌지 확인해보면 된다.
'문제풀이 > 최단경로' 카테고리의 다른 글
[Python/파이썬] 백준 21940번 가운데에서 만나기 (1) | 2023.10.23 |
---|---|
[Python/파이썬] 백준 16118번 달빛 여우 (1) | 2023.08.23 |
[Python/파이썬] 백준 11657번 타임머신 (0) | 2023.05.16 |
[Python/파이썬] 백준 10159번 저울 (1) | 2023.05.15 |
[Python/파이썬] 백준 1956번 운동 (1) | 2023.05.14 |