[BaekJoon 1976 : Graph Search, Python] - 여행가자 (dfs ver.)
2021, Dec 06
백준 여행가자 : 골드 4
Solution
import sys
sys.setrecursionlimit(10000000)
input = sys.stdin.readline
from collections import defaultdict
n, k = int(input()), int(input())
graph = defaultdict(list)
for i in range(n): # row
tmp = list(map(int, input().split()))
for j in range(n): # col
if tmp[j] == 1:
graph[i+1].append(j+1)
flag = False
def dfs(s, d, visited): # dfs
global flag
if s == d:
return True
if flag:
return True
for v in graph[s]:
if v not in visited:
if v == d:
flag = True
return True
else:
visited.append(v)
dfs(v, d, visited)
return flag
travel = list(map(int, input().split()))
if len(travel) == 1: # 여행할 도시가 1개뿐일 때
if travel[0] > n: # 주어진 도시 범위 밖의 여행지이면 NO
print("NO")
else:
print("YES")
sys.exit(0)
for k in range(len(travel)-1):
visited = [travel[k]]
flag = False
res = dfs(travel[k], travel[k+1], visited) # 매 경로마다 가능한지 여부 확인
if not res:
print("NO")
break
else:
print("YES")
풀이과정 및 느낀점
이 문제를 처음 봤을 때 가장 처음 떠오른 방법은 dfs 또는 bfs 를 활용하는 방법이었다.
여행경로 리스트(1-5-4-2-3)를 받아서 각각의 여행경로(1-5) 마다 실현가능한지 확인하는 dfs 함수를 짜고 한 번이라도 불가능한 경로가 나오면 NO 를 출력했다.
예외처리할 때 주의할 부분은
- 여행지 자체가 1개뿐일 때는 for 문을 타지 못하기 때문에 따로 처리를 해줘야 한다.
- 시작과 끝, 즉 (1->1) 이런 경로는 내 코드 상에서 visited 에 걸려 False 가 나오기 때문에 이 경우도 따로 함수 시작에 처리해줬다.
우선 이렇게 풀어서 정답이 나오긴 했지만, 시간이 1400ms 정도나 걸렸는데 다른 사람들 풀이를 보니 100ms 미만이었다.
참고해보니 Union-Find 알고리즘을 사용해서 시작과 도착경로가 동일한 집합 내에 속해있는지 여부를 따지면서 푼 듯했다.
다음에는 동일한 문제를 유니온 파인드 알고리즘을 활용해서 풀이한 문제를 올릴 예정이다.