DFS - 깊이 우선 탐색, BFS - 너비 우선 탐색

    DFS: 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘그래프는 노드와 간선으로 표현되며, 두 노드가 간선으로 연결되어 있을 시 인접하는 것 DFS는 주로 스택 자료구조를 이용한다. BFS: 가까운 노드부터 탐색하는 알고리즘, 주로 큐 자료구조 사용

     

     

    1012 유기농 배추

     

    import sys
    sys.setrecursionlimit(10000)
    
    t = int(input())
    
    dx = [-1, 1, 0, 0]
    dy = [0, 0, -1, 1]
    
    def dfs(x, y):  # 깊이우선탐색
      for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
    
        if nx<0 or nx>=m or ny<0 or ny>=n:
          continue
        elif graph[ny][nx] == 1:
          graph[ny][nx] = 0
          dfs(nx, ny) # 1이면 다음 노드 탐색
    
    for _ in range(t):
      m, n, k = map(int, input().split())
      graph = [[0 for _ in range(m)] for _ in range(n)]
    
      for _ in range(k):
        x, y = map(int, input().split())
        graph[y][x] = 1
    
      worm = 0
      for i in range(m):
        for j in range(n):
          if graph[j][i] == 1:
            dfs(i, j)
            worm += 1
      print(worm)

     

    자꾸 recursionerror가 떠서 코드 어디가 잘못된건가 진짜 열심히 찾았는데

    sys.setrecursionlimit(10000) 해주면 해결이 되는거였다..........

     

    11725 트리의 부모 찾기

    트리 상에서 연결된 두 정점 = 그래프

    코드 흐름: 그래프를 먼저 만들고

    그래프를 역추적....?

    n = int(input())
    
    graph = [[0]*(n+1) for _ in range(n+1)]
    
    for _ in range(n-1):
      a, b = map(int, input().split())
      graph[a][b] = 1
      graph[b][a] = 1

     

    근데 이런 식으로 연결된 정점이 10만개면.. 코드 잘못짜면 무조건 시간초과 뜰거같다.

    import sys
    sys.setrecursionlimit(1000000)
    
    n = int(input())
    tree = [[] for _ in range(n+1)]
    parent = [-1] * (n+1)
    for _ in range(n-1):
      a, b = map(int, input().split())
      tree[a].append(b)
      tree[b].append(a) # 연결된 트리 정보
    
    def dfs(n):
      for x in tree[n]: # 트리
        if parent[x] == -1: 
          parent[x] = n
          dfs(x)
    
    dfs(1)
    
    for i in range(2, n+1):
      print(parent[i])

     

    역시 메모리초과다

    는 pypy3이라서 초과떴다고하네용

     

    1926 그림

    이제 보자마자 약간 bfs 감이 오는듯아닌듯 일단 코드를 짜보자.

    from collections import deque
    
    n, m = map(int, input().split())
    
    dx = [0,0,1,-1]
    dy = [1,-1,0,0]
    
    def bfs(graph, a, b):
      q = deque()
      q.append((a, b))
      graph[a][b] = 0
      num = 1
    
      while q:
        x, y = q.popleft()
    
        for i in range(4):
          nx = x + dx[i]
          ny = y + dy[i]
          if nx < 0 or nx >= n or ny < 0 or ny >= m:
            continue
          elif graph[nx][ny] == 1:
            graph[nx][ny] = 0
            q.append((nx, ny))
            num += 1
    
      return num
    
    graph = [[0] * m for _ in range(n)]
    for i in range(n):
      graph[i] = list(map(int, input().split()))
    
    picture = []
    
    for i in range(n):
      for j in range(m):
        if graph[i][j] == 1:
          picture.append(bfs(graph, i, j))
    
    if len(picture) == 0:
      print(len(picture))
      print(0)
    else:
      print(len(picture))
      print(max(picture))

     

    2668 숫자 고르기

     

    1->3->1 5->5

    사이클을 찾고 그것들을 출력하는 문제같다.

     

    import sys
    
    sys.setrecursionlimit(1000000)
    
    n = int(input())
    
    graph = [[] for _ in range(n)]
    
    for i in range(1, n+1):
      tmp = int(input())
      graph[tmp-1].append(i)
    
    check = [0 for _ in range(n+1)]
    
    result = []
    
    def dfs(num, visited):
      visited.append(num)
      check[num] = 1
      for x in graph[num]:
        if x not in visited:
          dfs(x-1, visited.copy())
        else:
          result.extend(visited)
    
    blank = []
    for i in range(n):
      if not check[i]:
        dfs(i, blank) 
    
    print(len(result))
    
    result.sort()
    for x in result:
      print(x)

     

    어찌어찌 짜봤는데 메모리 초과가 떴다.

    메모리를 최대한 아끼기 위해서 defaultdict(?)를 사용해봤따

    import sys
    from collections import defaultdict
    
    sys.setrecursionlimit(1000000)
    
    n = int(input())
    
    graph = defaultdict(list)
    
    for i in range(1, n+1):
      tmp = int(input())
      graph[tmp].append(i)
    
    check = [0 for _ in range(n+1)]
    
    result = []
    
    def dfs(num, visited):
      visited.add(num)
      check[num] = 1
      for x in graph[num]:
        if x not in visited:
          dfs(x, visited.copy())
        else:
          result.extend(visited)
    
    for i in range(1, n+1):
      if not check[i]:
        dfs(i, set([])) 
    
    print(len(result))
    
    result.sort()
    for x in result:
      print(x)

     

    1987 알파벳

    일단 not visited 를 넣어줘야 할거같은 내용이다 방문하지 않은 알파벳이면 이동하고, 아니면 이동을 안해야됨

    dfs 쓰는 문제같

     

    r, c = map(int, input().split())
    board = []
    anstmp = 0
    for _ in range(r):
      board.append(list(input()))
    
    dx = [-1, 1, 0, 0]
    dy = [0, 0, -1, 1]
    
    
    def dfs(x, y, visited, maxlen):
      global anstmp
      anstmp = max(anstmp, maxlen)
      apb = board[x][y]
      for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
    
        if 0 <= nx < r and 0 <= ny < c: 
          if apb not in visited:
            visited.add(apb)
            dfs(nx, ny, visited, maxlen + 1)
            visited.remove(apb)
    
    visited = set([])
    
    dfs(0, 0, visited, 0)
    
    print(anstmp)

     

    시간초과가 떴다.

    코드상으론 괜찮았다고 생각했는데 아마 visited에 값을 넣고 빼주고 not in 이런식으로 해서 시간초과가 떴지 않나 하는 생각이 들어서 true false로 수정해봤다. 알파벳도 ord 사용해서 숫자로 바꿔줌

     

    r, c = map(int, input().split())
    anstmp = 1
    visited = [False] * 26
    board = [list(map(lambda x: ord(x) - 65, input())) for _ in range(r)]
    
    dx = [-1, 1, 0, 0]
    dy = [0, 0, -1, 1]
    
    
    def dfs(x, y, maxlen):
      global anstmp
      anstmp = max(anstmp, maxlen)
      for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
    
        if 0 <= nx < r and 0 <= ny < c: 
          if not visited[board[nx][ny]]:
            visited[board[nx][ny]] = True
            dfs(nx, ny, maxlen + 1)
            visited[board[nx][ny]] = False
    
    visited[board[0][0]] = True
    dfs(0, 0, anstmp)
    
    print(anstmp)

     

     

    Posted by 저본