Tag: graph theory
All the articles with the tag "graph theory".
첫째 줄에 동영상의 개수 N (1 ≤ N ≤ 5,000)과 질문의 개수 Q (1 ≤ Q ≤ 5,000)가 주어진다.
다음 N-1개의 줄에는 두 동영상을 연결하는 간선 정보 p, q, r이 주어진다. 이는 동영상 p와 동영상 q가 연관도 r로 연결되어 있음을 의미한다. (1 ≤ r ≤ 1,000,000,000)
다음 Q개의 줄에는 k, v가 주어진다. 이는 유사도가 k 이상인 동영상을 동영상 v를 기준으로 찾는 질의이다.
출력
Q개의 줄에 각 질문에 대한 답변을 출력한다.
이 문제는 트리 구조에서 특정 노드로부터 도달 가능한 노드들 중 경로상의 최소 가중치가 특정 값 이상인 노드의 개수를 세는 문제이다.
두 동영상 간의 유사도는 경로상의 최소 연관도이다. 따라서 시작 노드에서 BFS/DFS를 수행하며, 각 노드까지의 경로에서의 최소값을 유지하면서 탐색한다.
풀이 1: BFS를 이용한 방법
각 쿼리마다 BFS를 수행하여 유사도가 k 이상인 노드를 센다.
MooTube (Silver)
백준 15591번 'MooTube (Silver)' (골드 5) 문제 풀이. graph theory, graph traversal, bfs 로 접근했다.
첫째 줄에 N, L, R이 주어진다. (1 ≤ N ≤ 50, 1 ≤ L ≤ R ≤ 100)
둘째 줄부터 N개의 줄에 각 나라의 인구수가 주어진다. r행 c열에 주어지는 정수는 A[r][c]의 값이다. (0 ≤ A[r][c] ≤ 100)
인구 이동이 발생하는 일수가 2,000번 보다 작거나 같은 입력만 주어진다.
출력
인구 이동이 며칠 동안 발생하는지 첫째 줄에 출력한다.
이 문제는 시뮬레이션과 BFS를 결합한 문제이다. 매일 국경선이 열리는 나라들을 찾아 연합을 만들고, 인구를 재분배하는 과정을 반복해야 한다.
인구 이동이 일어나는 하루는 다음과 같은 과정을 거친다:
- 연합 찾기: BFS를 사용하여 국경선이 열리는 나라들의 연합을 찾는다.
- 인구 재분배: 각 연합의 평균 인구수를 계산하고 재분배한다.
- 종료 조건 확인: 어떤 연합도 만들어지지 않으면 인구 이동 종료.
1. 연합 찾기 (open 함수)
인구 이동
백준 16234번 '인구 이동' (골드 4) 문제 풀이. implementation, graph theory, graph traversal 로 접근했다.
N, M = map(int, input().split())
floor = [list(input()) for _ in range(N)]
def search_tiles(start, visited, tile_shape):
# 타일 모양에 따라 탐색 방향 설정
if tile_shape == '-':
dy, dx = 0, 1
else:
dy, dx = 1, 0
q = deque([start])
while q:
y, x = q.popleft()
ny, nx = y + dy, x + dx
# 범위 벗어났을 경우
if not (0 <= ny < N) or not (0 <= nx < M):
return 1
# 이미 방문했을 경우
if visited[ny][nx]:
return 1
# 타일 모양이 다를 경우
if floor[ny][nx] != tile_shape:
return 1
q.append((ny, nx))
visited[ny][nx] = True
visited = [[False] * M for _ in range(N)]
tile_cnt = 0
for y in range(N):
for x in range(M):
if visited[y][x]:
continue
tile_cnt += search_tiles((y, x), visited, floor[y][x])
print(tile_cnt)바닥 장식
백준 1388번 '바닥 장식' (실버 4) 문제 풀이. implementation, graph theory, graph traversal 로 접근했다.
| 건물 번호 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 필요 건물 | 0 | 0 | 0 | 0 | 1 |
탐색 완료: 1, 2, 3
이렇게 목표 건물이 4번이 queue에 들어와 탐색을 마치면 4번 건물을 지었다는 것이므로 탐색을 멈추고 저장해두었던 시간을 출력하면 된다.
이 문제의 입력으로 주어지는 건물들로 만들어진 그래프는 항상 방향성을 가지며, 항상 모든 건물이 건축 가능하도록 주어진다고 했기 때문에 acyclic이다. 즉 이 문제의 그래프는 DAG(Directed Acyclic Graph)이다. DAG에서 어떤 노드로 들어오는 간선의 개수를 indegree라고 하는데 이 indegree의 개수에 따라 정렬하는 것을 위상 정렬(topologicla sort)이라고 한다.
따라서 우리가 위에서 필요 건물(indegree)에 따라 정렬하여 시간을 계산한 것은 위상 정렬을 이용한 알고리즘인 것이다.
ACM Craft
백준 1005번 'ACM Craft' (골드 3) 문제 풀이. dynamic programming, graph theory, topological sort 로 접근했다.
입력
첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 ’.’, ’#’, ‘O’, ‘R’, ‘B’ 로 이루어져 있다. ’.’은 빈 칸을 의미하고, ’#‘은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, ‘O’는 구멍의 위치를 의미한다. ‘R’은 빨간 구슬의 위치, ‘B’는 파란 구슬의 위치이다.
입력되는 모든 보드의 가장자리에는 모두 ’#‘이 있다. 구멍의 개수는 한 개 이며, 빨간 구슬과 파란 구슬은 항상 1개가 주어진다.
출력
최소 몇 번 만에 빨간 구슬을 구멍을 통해 빼낼 수 있는지 출력한다. 만약, 10번 이하로 움직여서 빨간 구슬을 구멍을 통해 빼낼 수 없으면 -1을 출력한다.
맵을 BFS로 탐색하면서 시뮬레이션 하는 문제이다.
처음 시도한 방식은 정말 단순하게 모두 다 구현하는 것으로 맵 리스트 자체에서 구슬들을 실제로 움직이는 것까지 구현하였다.
구슬 탈출 2
백준 13460번 '구슬 탈출 2' (골드 1) 문제 풀이. implementation, graph theory, bfs 로 접근했다.