|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +thumbnail: /assets/img/GDSC_Dong-Eui_University_Vertical_color.png |
| 4 | +title: [백준 2606번 풀이 |
| 5 | +date: 2024-05-03T17:48:27Z |
| 6 | +tags: [] |
| 7 | +author: 이도원 |
| 8 | +--- |
| 9 | + |
| 10 | +# 백준 2606번 |
| 11 | + |
| 12 | +[백준 링크](https://www.acmicpc.net/problem/2606) |
| 13 | + |
| 14 | +## 1번째 문제 풀이(bfs) |
| 15 | + |
| 16 | +``` python |
| 17 | + |
| 18 | +from sys import stdin |
| 19 | +from collections import deque |
| 20 | + |
| 21 | +com = int(stdin.readline()) |
| 22 | +compair = int(stdin.readline()) |
| 23 | + |
| 24 | +graph = [[] for i in range(com + 1)] |
| 25 | +visited = [0] * (com + 1) |
| 26 | + |
| 27 | +for i in range(compair): |
| 28 | + com1, com2 = map(int, stdin.readline().split()) |
| 29 | + graph[com1] += [com2] |
| 30 | + graph[com2] += [com1] |
| 31 | + |
| 32 | +visited[1] = 1 |
| 33 | +queue = deque([1]) |
| 34 | + |
| 35 | +while queue: |
| 36 | + virus = queue.popleft() |
| 37 | + for nv in graph[virus]: |
| 38 | + if visited[nv] == 0: |
| 39 | + queue.append(nv) |
| 40 | + visited[nv] = 1 |
| 41 | + |
| 42 | +print(sum(visited)-1) |
| 43 | +``` |
| 44 | +- 문제 풀이 |
| 45 | +>bfs(너비 우선 탐색)을 이용하여 컴퓨터의 수와 컴퓨터 쌍의 수를 입력한 후 쌍의 수 만큼 입력을 받아서 양방향 연결을 시킵니다. |
| 46 | +>1번 컴퓨터를 방문 처리 하고 큐에 삽입 후 하나씩 꺼내 방문하지 않은 컴퓨터라면 큐에 추가하고 방문 처리를 해 반복을 하고 마지막으로 1번 컴퓨터를 제외한 방문한 |
| 47 | +>컴퓨터 수를 출력합니다. |
| 48 | +
|
| 49 | +## 2번째 문제 풀이(union find) |
| 50 | +``` python |
| 51 | +from sys import stdin |
| 52 | + |
| 53 | + |
| 54 | +def init_parent(parent, count) -> None: |
| 55 | + for i in range(count + 1): |
| 56 | + parent.append(i) |
| 57 | + |
| 58 | + |
| 59 | +def find_parent(parent, node) -> int: |
| 60 | + if parent[node] == node: |
| 61 | + return node |
| 62 | + parent[node] = find_parent(parent, parent[node]) |
| 63 | + return parent[node] |
| 64 | + |
| 65 | + |
| 66 | +def has_same_parent(parent, a, b) -> bool: |
| 67 | + return find_parent(parent, a) == find_parent(parent, b) |
| 68 | + |
| 69 | + |
| 70 | +def unite_parent(parent, a, b) -> None: |
| 71 | + a = find_parent(parent, a) |
| 72 | + b = find_parent(parent, b) |
| 73 | + if a < b: |
| 74 | + parent[b] = a |
| 75 | + else: |
| 76 | + parent[a] = b |
| 77 | + |
| 78 | + |
| 79 | +def main() -> None: |
| 80 | + link_to: list[int] = [] |
| 81 | + computer_count = int(stdin.readline()) |
| 82 | + connection_count = int(stdin.readline()) |
| 83 | + |
| 84 | + init_parent(link_to, computer_count) |
| 85 | + for _ in range(connection_count): |
| 86 | + from_x, to_y = map(int, stdin.readline().split()) |
| 87 | + unite_parent(link_to, from_x, to_y) |
| 88 | + # print(link_to) |
| 89 | + # print() |
| 90 | + |
| 91 | + count = sum( |
| 92 | + 1 for i in range(2, computer_count + 1) if has_same_parent(link_to, 1, i) |
| 93 | + ) |
| 94 | + print(count) |
| 95 | + |
| 96 | + |
| 97 | +if __name__ == "__main__": |
| 98 | + main() |
| 99 | +``` |
| 100 | + |
| 101 | +- 문제 풀이 |
| 102 | +union-find를 사용하여 문제를 풀기위해 기본 연산을 정의한다. |
| 103 | + |
| 104 | +find(find_parent) |
| 105 | +same(has_same_parent) |
| 106 | +unite(unite_parent) |
| 107 | + |
| 108 | +union-find, 서로소 집합의 자료 구조로 사용하기 위해 컴퓨터(node)의 개수 만큼 배열을 선언하며, 각각의 index의 요소가 |
| 109 | +자기자신을 가리키도록 한다. |
| 110 | + |
| 111 | +입력 받은 각 노드를 연결시킨다. 이때 unite를 사용하여 동일한 집합에 속함을 의미하도록 값을 저장한다. |
| 112 | +이때 find를 수행할 때 경로 압축을 통해 배열의 대표값을 가리키게된다. |
| 113 | + |
| 114 | +>[!info] |
| 115 | +>union-find를 사용할 경우 각 배열이 요소가 가리키는 값은 각 노드가 속하는 집합의 대표값이 된다. |
| 116 | +
|
| 117 | +집합에 속한 노드의 연결성이 보장되었으므로, 1번(노드)을 제외한 모든 요소(노드)에 대하여 same을 통해 해당 노드가 1번 |
| 118 | +컴퓨터와 연결된 집합에 속하는지 확인하며, 동일한 집합에 속하는 경우 count를 증가시킨다. |
| 119 | + |
| 120 | +계산된 count 값이 정답이 된다. |
| 121 | + |
| 122 | + |
| 123 | +# 백준 16928번 |
| 124 | + |
| 125 | +``` python |
| 126 | +from sys import stdin |
| 127 | +from collections import deque |
| 128 | + |
| 129 | + |
| 130 | +roll_count = 0 |
| 131 | +board = [location for location in range(101)] |
| 132 | +visited = [False]*101 |
| 133 | + |
| 134 | +def bfs(start_num): |
| 135 | + visited[start_num] = True |
| 136 | + q = deque() |
| 137 | + q.append((start_num,0)) |
| 138 | + while len(q) > 0: |
| 139 | + now_location,now_roll_count = q.popleft() |
| 140 | + if now_location == 100: |
| 141 | + return now_roll_count |
| 142 | + for dice_eye in range(1,6+1): |
| 143 | + if now_location + dice_eye <= 100 and not visited[now_location + dice_eye]: |
| 144 | + visited[now_location+dice_eye] = True |
| 145 | + visited[board[now_location+dice_eye]] = True |
| 146 | + q.append((board[now_location+dice_eye],now_roll_count+1)) |
| 147 | + |
| 148 | +n,m = map(int,stdin.readline().strip().split()) |
| 149 | + |
| 150 | +for i in range(n): |
| 151 | + start,end = map(int,stdin.readline().strip().split()) |
| 152 | + board[start] = end |
| 153 | +for i in range(m): |
| 154 | + start,end = map(int,stdin.readline().strip().split()) |
| 155 | + board[start] = end |
| 156 | +print(bfs(1)) |
| 157 | +``` |
| 158 | +- 문제 풀이 |
| 159 | + |
| 160 | +>기본적인 bfs, 주사위 눈 1..6 고려해서 진행, board가 뱀, 사다리면 도착점 위치로 지정 후 이동, 현재 위치가 100일 때 주사위 수 반환 |
| 161 | +>(단, 큐에 푸시할 때 방문했음을 현재 점과 이동 점의 방문을 표시할 것) |
| 162 | +
|
0 commit comments