dfs 문제 특징
백준 2문제를 참고로 정리하자.
https://www.acmicpc.net/problem/1987
다양한 크기의 보드에 말판이 올라가 있다. 보드는 격자 무늬로 나누어져 있으며 각 칸마다 알파벳이 적혀있다. 지나온 경로에서 없는 알파벳만을 밟으며 이동할 수 있는 최대 거리를 찾자.
https://www.acmicpc.net/problem/1967
트리 안의 서로 다른 두 점의 경로 중 가장 긴 것을 트리의 지름이라 한다. 이 때, 간선 간에는 다양한 가중치 값이 존재한다.
R,C = map(int,input().split())
arr = [list(input()) for _ in range(R)]
check = [[0]*C for _ in range(R)]
A = ord('A')
stack = [(0,0,1,1<<(ord(arr[0][0])-A))]
result = 0
dx = [-1,1,0,0]
dy = [0,0,1,-1]
while stack:
x,y,cnt,total = stack.pop()
if result < cnt:
result = cnt
if result == 26:
break
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < R and 0<= ny <C:
if (total & (1<<ord(arr[nx][ny])- A)) == 0:
temp = total | (1<<(ord(arr[nx][ny])-A))
if check[nx][ny] != temp:
check[nx][ny] = temp
stack.append((nx,ny,cnt+1,temp))
print(result)
from sys import stdin
input = stdin.readline
def solve():
R, C = map(int, input().split())
length = R * C
visited = [set() for _ in range(length)]
arr = [0] * length
for i in range(R):
arr[i * C:(i+1) * C] = [*map(lambda char: 1 << (ord(char) - 65), input()[:-1])]
ans = 0
que = {0}
visited[0].add(arr[0])
for k in range(27):
if k == 26 or not que:
ans = k
break
new_que = set()
new_visited = [set() for _ in range(length)]
while que:
cur_pos = que.pop()
i, j = cur_pos // C, cur_pos % C
adj = []
if i > 0: adj.append(cur_pos-C)
if j > 0: adj.append(cur_pos-1)
if i < R - 1: adj.append(cur_pos+C)
if j < C - 1: adj.append(cur_pos+1)
for neighbor_pos in adj:
neighbor_alpha = arr[neighbor_pos]
flag = True
for visited_alpha in visited[cur_pos]:
if not neighbor_alpha & visited_alpha:
new_visited[neighbor_pos].add(visited_alpha | neighbor_alpha)
if flag:
new_que.add(neighbor_pos)
flag = False
que = new_que
visited = new_visited
return ans
if __name__ == '__main__':
print(solve())
import sys
def dfs(x):
visited = [-1] * (N+1)
visited[x] = 0
q = [x]
while q:
now = q.pop()
for i, cost in tree[now]:
if visited[i] == -1:
visited[i] = visited[now] + cost
q.append(i)
return visited
def main():
global tree, N
I = sys.stdin.readline
N = int(I())
tree = [[] for _ in range(N+1)]
for _ in range(N-1):
a, b, c = map(int,I().split())
tree[a].append((b, c))
tree[b].append((a, c))
res1 = bfs(1)
idx = res1.index(max(res1))
print(max(bfs(idx)))
if __name__ == "__main__":
main()
dfs로만 풀 수 있는 문제의 특징에서 다음의 것을 정리하자.
우선 function object가 call stack에서 얼마나 많은 메모리를 할당받는 지 모른다. 컴퓨터 구조와도 연관이 있어서 나중에 알아봐야겠다. 참고 코드 모두 list를 이용해 pop, append로 구현했으므로 list 구현 쪽으로 바꾸는 것이 좋을 듯 싶다. 다른 차이는 잘 모르겠다.
알파벳 문제의 경우, 비트를 이용해서 search의 시간을 대폭 줄였다. 트리의 지름 문제의 경우, 트리의 특성을 이용해서 dfs 호출을 최소화하였다. 아직 명확하게 dfs를 이해했다고 할 수 없어서 더 풀어볼까 한다.