[백준 파이썬] 11581 구호물자

 

 

11581번: 구호물자

서기 2050년 엄청나게 강력한 폭풍이 인천을 강타했다. 강력한 폭풍의 영향으로 모든 사람은 대피소로 대피하였으며, 많은 도로가 유실되었다. 그나마 남아있는 도로도 모든 표지판과 가로등이

www.acmicpc.net

문제

etc-image-0

그래프에서 시작 정점으로 다시 돌아오는 경우를 판단하는 문제이다.


 

아이디어

DFS를 이용해서 방문여부를 판단하며 문제를 풀 수 있을거라 생각했다.

하지만 플로이드를 연습할 겸 플로이드 워셜로 문제를 풀어보았다.

 

플로이드 워셜은 모든 정점의 경로를 탐색하기때문에 시작지점으로 다시 돌아올 경우를 판단할 수 있다.


풀이

N = int(input())

graph = [[0] * (N+1) for _ in range(N+1)]

for i in range(1, N):
  temp = int(input())
  a = list(map(int, input().split()))

  for j in a:
    graph[i][j] = 1

 

그래프의 기본 정보를 입력해준다.

처음 정보가 입력된 그래프에는 연결된 간선의 정보가 들어있다.

for k in range(1, N+1):
  for i in range(1, N+1):
    for j in range(1, N+1):
      if graph[i][k] and graph[k][j]:
        graph[i][j] = 1

그 후 플로이드 워셜을 사용한다.

이 때 만약 i와 j가 같고 

graph[i][k] 값과 graph[k][j] 값이 모두 1일경우 

한 정점을 지나 다시 돌아온다는 의미이므로 자기자신에 대한 경로를 1로 초기화한다.

 

for i in range(1, N+1):
  if graph[1][i] == 1 and graph[i][i] == 1:
    ans = "CYCLE"

 

Cycle을 판단하기 위해 그래프를 탐색한다.

자기자신에 대한 경로가 1일경우 위에서와 같이 다른 정점으로 갔다 다시 돌아왔다는 의미이므로 순환이 된것이다.

또한 시작지점에서 다시 시작지점으로 돌아와야하므로 시작지점과 연결되어있는지 판단한다.

 


코드

N = int(input())

graph = [[0] * (N+1) for _ in range(N+1)]

for i in range(1, N):
  temp = int(input())
  a = list(map(int, input().split()))

  for j in a:
    graph[i][j] = 1




for k in range(1, N+1):
  for i in range(1, N+1):
    for j in range(1, N+1):
      if graph[i][k] and graph[k][j]:
        graph[i][j] = 1


ans = "NO CYCLE"

for i in range(1, N+1):
  if graph[1][i] == 1 and graph[i][i] == 1:
    ans = "CYCLE"

print(ans)

 

'알고리즘' 카테고리의 다른 글

[백준 파이썬] 1261 알고스팟  (0) 2023.12.27
[백준 파이썬] 15686 치킨 배달  (0) 2023.12.18
[백준 파이썬] 11404 플로이드  (0) 2023.12.13
[백준 파이썬] 9251 LCS  (0) 2023.12.11
[백준 파이썬] 1865 웜홀  (2) 2023.12.08