링크 : https://www.acmicpc.net/problem/18232
문제
그냥 BFS만 돌리면 되지않을까?
딱히 가중치가 있지도않고, 그냥 노드로 이동하는 문제인것같다.
텔레포트가 혹시 단방향인가? 에 대한 생각을 해봣는데, 점 x의 텔레포트와 점 y의 텔레포트가 연결되어있다는 뜻 에서 양방향이라고 생각했다
테스트케이스
# N, M = 10 ,3
# S, E = 2, 5
# graph = [[], [6, 3], [8], [1], [], [], [1], [], [2], [], []]
메모리 초과되는 소스코드
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
S, E = map(int ,input().split())
graph = [ [] for _ in range(N+1)]
for _ in range(M) :
x, y = map(int ,input().split())
graph[x].append(y)
graph[y].append(x)
from collections import deque
Q = deque()
Q.append((S,0))
while Q :
location, cost = Q.popleft()
if location == E :
print(cost)
break
for i in [location+1, location-1] :
if 1<i<N :
Q.append((i,cost+1))
if graph[location] :
for i in graph[location] :
Q.append((i, cost+1))
왜 메모리 초과가 날까?
이 소스코드의 문제점은 ‘노드의 방문여부와 상관없이 큐에서 보내면 다시 방문해야한다는 ‘것 때문이다
가령 시작지점이 2이고, 1→ 3으로 가는 텔레포트가 있다면
2 → (-1) → 1 → (텔레포트) → 3 → (-1) → 2 이런식으로 무한루프를 돌게되서
결국 방문처리가 의미가없게되더라
그래서 해결방법으로는
이번엔 어떤 부분을 추가해줬냐면 dp[]
배열을 선언해서
이미 방문한 노드면 새로운 큐를 돌게 만들었다
이번엔 시간초과 나는 소스코드
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
S, E = map(int ,input().split())
graph = [ [] for _ in range(N+1)]
for _ in range(M) :
x, y = map(int ,input().split())
graph[x].append(y)
graph[y].append(x)
from collections import deque
Q = deque()
Q.append((S,0))
dp = [int(1e7) for _ in range(N+1)] #무지하게 큰 값으로 초기화
dp[S] = 0
while Q :
location, cost = Q.popleft()
#종료조건
if location == E :
print(cost)
break
if cost > dp[location] :
continue
else :
dp[location] = cost
for i in [location+1, location-1] :
if 1<i<N :
Q.append((i,cost+1))
if graph[location] :
for i in graph[location] :
Q.append((i, cost+1))
근데 시간초과가 나더라
왜 시간초과가 날까를 생각해봤는데 if cost > dp[location]
의 위치가 문제였던것같다
이런식으로 dp
테이블을 활용해서 하는 BFS는 Queue에 값을 넣어줄때 append()
메소드를 쓰는데
이게 O(N)인가? 그렇다.
앞에서부터 쭉쭉쭉 연결되어있는 리스트에서 맨 뒤로 가야하기때문에 O(N)이 든다
근데 O(N) 들여서 꾸역꾸역 리스트 뒤에 붙혀놨더니, 이미 방문한 노드라고 continue
를 돌린다?
이만한 낭비가 없다. 그래서 애초에 무지성으로 추가하지말고, 넣을지말지를 확인하고 넣으면 좋을것같다
문제없는 코드
# N, M = 10 ,3
# S, E = 2, 5
# graph = [[], [6, 3], [8], [1], [], [], [1], [], [2], [], []]
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
S, E = map(int ,input().split())
graph = [ [] for _ in range(N+1)]
for _ in range(M) :
x, y = map(int ,input().split())
graph[x].append(y)
graph[y].append(x)
from collections import deque
Q = deque()
Q.append(S)
dp = [int(1e7) for _ in range(N+1)] #무지하게 큰 값으로 초기화
dp[S] = 0
while Q :
location = Q.popleft()
#종료조건
if location == E :
print(dp[location])
break
for i in [location+1, location-1] :
if (1<=i<=N) and (dp[i] > dp[location]+1):
Q.append(i)
dp[i] = dp[location]+1
if graph[location] :
for i in graph[location] :
if (dp[i] > dp[location]+1) :
Q.append(i)
dp[i] = dp[location]+1
# print(dp)
자잘하게 틀렸던 iteration
범위를 재설정 해줬다
그리고 dp[i] > dp[location]+1
로 ‘이 노드를 가도 되는지' 확인 후에 BFS()에 넣었다
'CodingTest' 카테고리의 다른 글
백준 2661 좋은수열 (0) | 2022.08.17 |
---|---|
프로그래머스 보석쇼핑 67258 파이썬 (0) | 2022.07.20 |
백준 10826 피보나치수4 파이썬 (0) | 2022.07.20 |
리트코드 Tapping Rain Water (0) | 2022.07.13 |
백준 2606 바이러스 (0) | 2022.07.13 |