Skip to content

Commit 46b617d

Browse files
committed
[BOJ] 3665. 최종 순위 / 골드1 / 84분 / 힌트->성공
1 parent eeadc02 commit 46b617d

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import sys
2+
from collections import deque
3+
4+
input = sys.stdin.readline
5+
6+
'''
7+
1. 일반적인 위상정렬 구현
8+
2. 예외조건 추가 : 일관성이 없는 정보일 경우(IMPOSSIBEL) / 발표된 정보만 가지고 확실한 순위를 만들 수 없는 경우(?)
9+
'''
10+
11+
t = int(input()) # 테스트케이스 개수
12+
for _ in range(t):
13+
# 각 테스트 케이스에 대해 팀의 수와 작년 순위 정보를 입력받음
14+
n = int(input()) # 팀의 수
15+
info = list(map(int, input().split())) # 작년에 i등한 순서 정보
16+
17+
# 초기 그래프와 진입차수 초기화
18+
graph = [[] for _ in range(n + 1)]
19+
indegree = [0] * (n + 1) # 진입차수 0으로 초기화
20+
21+
# 작년 순위 정보를 바탕으로 그래프 생성
22+
for i in range(1, n + 1):
23+
for j in range(i + 1, n + 1):
24+
graph[i].append(info[j - 1])
25+
indegree[info[j - 1]] += 1
26+
27+
# 순위가 변경된 팀 쌍의 수
28+
m = int(input()) # 상대적인 등수가 바뀐 쌍의 수 m
29+
for _ in range(m):
30+
a, b = map(int, input().split()) # 순위가 변경된 두 팀
31+
32+
# 간선 방향을 바꾸기 위한 처리
33+
a_idx = info.index(a) + 1
34+
b_idx = info.index(b) + 1
35+
36+
# 기존에 b가 a보다 뒤에 있는 경우: 간선을 제거하고 새 순서로 간선 추가
37+
if a in graph[b_idx]:
38+
# 더 높았던 순위에서 제거
39+
graph[b_idx].remove(a)
40+
indegree[b] += 1
41+
# 새로 갱신된 순위 반영
42+
graph[a_idx].append(b)
43+
indegree[a] -= 1
44+
else: # 반대 경우: 간선 방향을 다시 바꿔야 하는 경우
45+
graph[a_idx].remove(b)
46+
indegree[b] -= 1
47+
graph[b_idx].append(a)
48+
indegree[a] += 1
49+
50+
51+
# 위상 정렬 수행
52+
def topology_sort():
53+
ranking = [] # 최종 순위를 저장할 리스트
54+
queue = deque()
55+
56+
# 큐에 진입차수가 0인 팀(노드)을 모두 추가
57+
for i in range(1, len(indegree)):
58+
if indegree[i] == 0:
59+
queue.append(i)
60+
61+
# 진입 차수가 0인 정점이 없어 큐가 비어 있다면, 순위를 결정할 수 없다는 의미로 "IMPOSSIBLE" 출력
62+
if not queue:
63+
print("IMPOSSIBLE")
64+
return
65+
66+
able = True # 순위 결정 가능 여부
67+
68+
# 큐가 빌 때까지 반복
69+
while queue:
70+
# 큐에서 노드를 꺼내고 최종 순위에 추가
71+
now = queue.popleft()
72+
ranking.append(now)
73+
74+
# 해당 노드와 연결된 다른 노드들의 진입차수를 1씩 감소
75+
for i in graph[info.index(now) + 1]:
76+
indegree[i] -= 1
77+
# 진입차수가 0이 된 노드를 큐에 삽입
78+
if indegree[i] == 0:
79+
queue.append(i)
80+
# 진입차수가 음수가 되는 경우는 잘못된 정보로 간주
81+
elif indegree[i] < 0:
82+
able = False
83+
break
84+
85+
# 출력 조건을 확인하여 결과 출력
86+
if not able or n != len(ranking): # 전체 노드 개수와 결과의 노드 개수가 다를 경우
87+
print("IMPOSSIBLE")
88+
else:
89+
# 확실한 순서가 결정된 경우 순위를 출력
90+
print(" ".join(map(str, ranking)))
91+
92+
topology_sort()

0 commit comments

Comments
 (0)