Skip to content

Minjeong / 7월 1주차 / 4문제#38

Merged
zaqquum merged 4 commits intomainfrom
minjeong
Jul 8, 2024
Merged

Minjeong / 7월 1주차 / 4문제#38
zaqquum merged 4 commits intomainfrom
minjeong

Conversation

@Mingguriguri
Copy link
Collaborator

주 목표 문제 수: 3개

푼 문제


백준 #24479. 알고리즘 수업 - 깊이 우선 탐색 1: 그래프 / 실버2

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. 먼저 재귀로 탐색하기 때문에 **RecursionError**를 방지하기 위해 최대 재귀 한도 깊이를 설정해준다. 100,000으로 설정해준 이유는 문제에서 주어준 노드 n의 최댓값이 100,000이기 때문이다.
  2. DFS 함수
    1. 방문할 경우, 방문 순서를 나타내는 order 변수를 visited 리스트에 대입하여 방문순서를 기록해준다.
    2. 그 다음 다음 순서로 넘어가기 위해 order 에 +1을 한다.
    3. 오름차순으로 인접 노드로 방문하기 위해서 해당 노드와 연결된 노드를 정렬시킨 후 for문으로 순회한다. 만약 순회한 노드가 방문하지 않은 노드라면 dfs 탐색을 시도한다.
  3. 정점의 수 n, 간선의 수 m, 시작정점 r을 입력받고, 빈 그래프인 graph 리스트를 초기화한다.
  4. visited 리스트는 1부터 n까지의 노드를 모두 0으로 초기화한다. 문제에서 방문할 수 없는 노드면 0을 출력하라고 했으므로 0으로 설정한다.
  5. 그 다음 u, v입력받아 graph를 연결해준다.
  6. graph에서 r번 노트부터 dfs 탐색하며, 해당 노드에 방문했으면 방문 순서를 기록해주고, 방문 순서를 +1 해준 후, 인접하고 방문하지 않은 노드를 dfs 탐색한다..

🚩제출한 코드

import sys
sys.setrecursionlimit(10**6) # 최대 재귀한도 깊이
input = sys.stdin.readline

def dfs(v):
    global order
    visited[v] = order  # 방문하면 순서 넣기
    order += 1          # 다음 순서로 넘어가기
    for u in sorted(graph[v]): # 오름차순으로 인접노드 방문하기 위해 정렬
        if visited[u] == 0: # 방문 안 한 노드면 dfs탐색
            dfs(u)

# n: 정점의 수, m: 간선의 수, r: 시작 정점
n, m, r = map(int, input().strip().split())
graph = [[] for _ in range(n + 1)]
visited = [0] * (n + 1) # 방문 순서 저장. 0이면 방문 X
order = 1

# m개의 간선 정보를 입력받아 그래프로 연결하기
for _ in range(m):
    u, v = map(int, input().strip().split())
    graph[u].append(v)
    graph[v].append(u)

dfs(r)

# 해당노드를 몇 번째로 방문했는지 출력
for i in range(1, n + 1):
    print(visited[i])

💡TIL

배운 점이 있다면 입력해주세요

  • dfs 중에서도 기본적인 문제인데 문제의 의도를 정확히 파악하는 것도 중요한 것 같다.
  • 시행착오를 겪으며 다시 dfs에 대한 개념을 코드로 정리해보는 시간이었다.

백준 #24480. 알고리즘 수업 - 깊이 우선 탐색 2: 그래프 / 실버2

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. 먼저 재귀로 탐색하기 때문에 **RecursionError**를 방지하기 위해 최대 재귀 한도 깊이를 설정해준다. 100,000으로 설정해준 이유는 문제에서 주어준 노드 n의 최댓값이 100,000이기 때문이다.
  2. DFS 함수
    1. 방문할 경우, 방문 순서를 나타내는 order 변수를 visited 리스트에 대입하여 방문순서를 기록해준다.
    2. 그 다음 다음 순서로 넘어가기 위해 order 에 +1을 한다.
    3. 내림차순으로 인접 노드로 방문하기 위해서 해당 노드와 연결된 노드를 정렬시킨 후 for문으로 순회한다. 만약 순회한 노드가 방문하지 않은 노드라면 dfs 탐색을 시도한다.
  3. 정점의 수 n, 간선의 수 m, 시작정점 r을 입력받고, 빈 그래프인 graph 리스트를 초기화한다.
  4. visited 리스트는 1부터 n까지의 노드를 모두 0으로 초기화한다. 문제에서 방문할 수 없는 노드면 0을 출력하라고 했으므로 0으로 설정한다.
  5. 그 다음 u, v입력받아 graph를 연결해준다.
  6. graph에서 r번 노트부터 dfs 탐색하며, 해당 노드에 방문했으면 방문 순서를 기록해주고, 방문 순서를 +1 해준 후, 인접하고 방문하지 않은 노드를 dfs 탐색한다..

🚩제출한 코드

import sys
sys.setrecursionlimit(10**6) # 최대 재귀한도 깊이
input = sys.stdin.readline

def dfs(v):
    global order
    visited[v] = order  # 방문하면 순서 넣기
    order += 1          # 다음 순서로 넘어가기
    for u in sorted(graph[v]): # 오름차순으로 인접노드 방문하기 위해 정렬
        if visited[u] == 0: # 방문 안 한 노드면 dfs탐색
            dfs(u)

# n: 정점의 수, m: 간선의 수, r: 시작 정점
n, m, r = map(int, input().strip().split())
graph = [[] for _ in range(n + 1)]
visited = [0] * (n + 1) # 방문 순서 저장. 0이면 방문 X
order = 1

# m개의 간선 정보를 입력받아 그래프로 연결하기
for _ in range(m):
    u, v = map(int, input().strip().split())
    graph[u].append(v)
    graph[v].append(u)

dfs(r)

# 해당노드를 몇 번째로 방문했는지 출력
for i in range(1, n + 1):
    print(visited[i])

💡TIL

배운 점이 있다면 입력해주세요

  • 이전 문제 (#24479)를 응용하는 문제라 손쉽게 풀 수 있었다. 한 번 더 응용해보니까 머리에 더 잘 들어왔다.
  • **sort() vs sorted()
    • sort(): 리스트만 정렬할 수 있고, 공간 절약을 위해 리스트를 제자리에서 수정한다. 즉, 원본을 바로 정렬하기 때문에 리스트를 반환하지 않는다.
    • sorted(): iterable한 객체(리스트, 튜플, 딕셔너리 등)을 모두 정렬시켜준다. 새로 정렬된 객체를 ‘리스트’로 반환한다.

백준 #24444. 알고리즘 수업 - 너비 우선 탐색 1](https://www.acmicpc.net/problem/24444): 그래프 / 실버2

정리한 링크: (바로가기

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. bfs함수
    1. deque 라이브러리를 import하여 queue를 deque로 형변환한다.
    2. queue에 시작 노드를 enqueue한다.
    3. 방문순서를 나타내는 order 변수를 1로 초기화한다.
    4. 큐가 빌 때까지 아래 과정을 반복한다.
      1. 먼저 큐에서 가장 앞에 있는 원소를 dequeue 해서 node에 저장한다.
      2. 이 노드가 방문되지 않은 원소라면 방문한 순서(order)를 visited 리스트에 저장하고, 다음 순서로 넘어간다.
      3. 이 노드와 연결된 노드를 오름차순으로 정렬하여 for loop로 순회한다. 연결된 노드 중에서 방문 안한 노드를 큐에 enqueue한다.
  2. 정점의 수 n, 간선의 수 m, 시작정점 r을 입력받고, 빈 그래프인 graph 리스트를 초기화한다.
  3. visited 리스트는 1부터 n까지의 노드를 모두 0으로 초기화한다. 문제에서 방문할 수 없는 노드면 0을 출력하라고 했으므로 0으로 설정한다.
  4. 그 다음 u, v입력받아 graph를 연결해준다.
  5. graph에서 r번 노트부터 bfs 탐색하며, 해당 노드에 방문했으면 방문 순서를 기록해주고, 방문 순서를 +1 해준 후, 인접하고 방문하지 않은 노드를 bfs 탐색한다..

🚩제출한 코드

import sys
from collections import deque

input = sys.stdin.readline

# BFS 함수
def bfs(v, graph, visited):
    order = 1
    # 큐
    queue = deque([v])

    while queue: # 큐가 빌 때까지 반복
        # 큐에서 원소를 하나 뽑아 출력한다. 
        node = queue.popleft()
        if visited[node] == 0:
            visited[node] = order  # 방문하면 순서 넣기
            order += 1          # 다음 순서로 넘어가기

            for u in sorted(graph[node]): # 오름차순 인접노드 방문하기 위해 정렬
                if visited[u] == 0: # 방문 안 한 노드면 bfs 탐색
                    queue.append(u)

# 초기화
n, m, r = map(int, input().strip().split()) # n: 정점의 수, m: 간선의 수, r: 시작 정점
graph = [[] for _ in range(n+1)]
visited = [0] * (n+1)

# 그래프 연결
for _ in range(m):
    u, v = map(int, input().strip().split())
    graph[u].append(v)
    graph[v].append(u)

bfs(r, graph, visited)

# 해당노드를 몇 번째로 방문했는지 출력
for i in range(1, len(visited)):
    print(visited[i])

💡TIL

배운 점이 있다면 입력해주세요

  • bfs를 어떻게 구현할 지 까먹어서 다시 찾아보았다.

    from collections import deque
    
    # BFS 함수 정의
    def bfs(graph, start, visited):
        # 큐(Queue) 구현을 위해 deque 라이브러리 사용
        queue = deque([start])
        # 현재 노드를 방문 처리
        visited[start] = True
        # 큐가 빌 때까지 반복
        while queue:
            # 큐에서 하나의 원소를 뽑아 출력
            v = queue.popleft()
            print(v, end=' ')
            # 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입
            for i in graph[v]:
                if not visited[i]:
                    queue.append(i)
                    visited[i] = True
    
    # 각 노드가 연결된 정보를 리스트 자료형으로 표현(2차원 리스트)
    graph = [
      [],
      [2, 3, 8],
      [1, 7],
      [1, 4, 5],
      [3, 5],
      [3, 4],
      [7],
      [2, 6, 8],
      [1, 7]
    ]
    
    # 각 노드가 방문된 정보를 리스트 자료형으로 표현(1차원 리스트)
    visited = [False] * 9
    
    # 정의된 BFS 함수 호출
    bfs(graph, 1, visited)
    1. deque 라이브러리를 import한다.
    2. queue에 시작 노드를 enqueue한다.
    3. 큐가 빌 때까지 반복하면서 큐에서 원소를 dequeue 해서 해당 원소와 연결되었지만 아직 방문하지 않은 원소들을 큐에 삽입한다.

백준 #24445. 알고리즘 수업 - 너비 우선 탐색 2](https://www.acmicpc.net/problem/24445): 그래프 / 실버2

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. bfs함수
    1. deque 라이브러리를 import하여 queue를 deque로 형변환한다.
    2. queue에 시작 노드를 enqueue한다.
    3. 방문순서를 나타내는 order 변수를 1로 초기화한다.
    4. 큐가 빌 때까지 아래 과정을 반복한다.
      1. 먼저 큐에서 가장 앞에 있는 원소를 dequeue 해서 node에 저장한다.
      2. 이 노드가 방문되지 않은 원소라면 방문한 순서(order)를 visited 리스트에 저장하고, 다음 순서로 넘어간다.
      3. 이 노드와 연결된 노드를 오름차순으로 정렬하여 for loop로 순회한다. 연결된 노드 중에서 방문 안한 노드를 큐에 enqueue한다.
  2. 정점의 수 n, 간선의 수 m, 시작정점 r을 입력받고, 빈 그래프인 graph 리스트를 초기화한다.
  3. visited 리스트는 1부터 n까지의 노드를 모두 0으로 초기화한다. 문제에서 방문할 수 없는 노드면 0을 출력하라고 했으므로 0으로 설정한다.
  4. 그 다음 u, v입력받아 graph를 연결해준다.
  5. graph에서 r번 노트부터 bfs 탐색하며, 해당 노드에 방문했으면 방문 순서를 기록해주고, 방문 순서를 +1 해준 후, 인접하고 방문하지 않은 노드를 bfs 탐색한다..

🚩제출한 코드

import sys
from collections import deque

input = sys.stdin.readline

# BFS 함수
def bfs(v, graph, visited):
    order = 1
    # 큐
    queue = deque([v])

    while queue: # 큐가 빌 때까지 반복
        # 큐에서 원소를 하나 뽑아 출력한다. 
        node = queue.popleft()
        if visited[node] == 0:
            visited[node] = order  # 방문하면 순서 넣기
            order += 1          # 다음 순서로 넘어가기

            for u in sorted(graph[node]): # 오름차순 인접노드 방문하기 위해 정렬
                if visited[u] == 0: # 방문 안 한 노드면 bfs 탐색
                    queue.append(u)

# 초기화
n, m, r = map(int, input().strip().split()) # n: 정점의 수, m: 간선의 수, r: 시작 정점
graph = [[] for _ in range(n+1)]
visited = [0] * (n+1)

# 그래프 연결
for _ in range(m):
    u, v = map(int, input().strip().split())
    graph[u].append(v)
    graph[v].append(u)

bfs(r, graph, visited)

# 해당노드를 몇 번째로 방문했는지 출력
for i in range(1, len(visited)):
    print(visited[i])

@Mingguriguri Mingguriguri changed the title Minjeong / 7월 1주차 / 3문제 Minjeong / 7월 1주차 / 4문제 Jul 8, 2024
@zaqquum
Copy link
Collaborator

zaqquum commented Jul 8, 2024

고생하셨습니다

Copy link
Collaborator

@zaqquum zaqquum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다.

@zaqquum zaqquum merged commit 2a9248a into main Jul 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants