https://programmers.co.kr/learn/courses/30/lessons/62050
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
from collections import deque, defaultdict
import math
import sys
sys.setrecursionlimit(10 ** 6)
# Union Find 함수
def find_parent(x, parent):
if x == parent[x]:
return x
else:
p = find_parent(parent[x], parent)
parent[x] = p
return p
# Union Find 함수
def union(x, y, parent):
x = find_parent(x, parent)
y = find_parent(y, parent)
parent[y] = x
# 처음 그룹을 나누기 위한 BFS
def bfs(land, start, visited, height, group):
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
queue = deque()
queue.append(start)
while queue:
y, x = queue.popleft()
visited[y][x] = group
for dy, dx in dirs:
ny, nx = y + dy, x + dx
if 0 <= ny < len(land) and 0 <= nx < len(land[0]) and visited[ny][nx] == 0 and abs \
(land[ny][nx] - land[y][x]) <= height:
visited[ny][nx] = group
queue.append((ny, nx))
# 인접한 블록이 그룹이 다른 경우 사다리를 놓을 후보지에 추가
def find_height(visited, maps, table):
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for y in range(len(maps)):
for x in range(len(maps[0])):
rx = x + 1
dy = y + 1
if rx < len(maps[0]) and visited[y][x] != visited[y][rx]:
a, b = min(visited[y][x], visited[y][rx]), max(visited[y][x], visited[y][rx])
table[(a, b)] = min(table[(a, b)], abs(maps[y][x] - maps[y][rx]))
if dy < len(maps) and visited[dy][x] != visited[y][x]:
a, b = min(visited[dy][x], visited[y][x]), max(visited[dy][x], visited[y][x])
table[(a, b)] = min(table[(a, b)], abs(maps[dy][x] - maps[y][x]))
def solution(land, height):
visited = [[0 for _ in range(len(land[0]))] for _ in range(len(land))]
group = 1
for y in range(len(land)):
for x in range(len(land[0])):
if visited[y][x] == 0:
bfs(land, (y, x), visited, height, group)
group += 1
table = defaultdict(lambda: math.inf)
find_height(visited, land, table)
# 사다리 놓을 후보를 작은 순서로 정렬, 앞에서 빼내면서 담으면 답이 된다
table = sorted(table.items(), key=lambda x: x[1])
answer = 0
nodes = {i: i for i in range(1, group)}
for (a, b), value in table:
# 두 그룹이 같은 그룹인지 판단
if find_parent(a, nodes) != find_parent(b, nodes):
union(a, b, nodes)
answer += value
if len(nodes.values()) == 1:
return answer
return answer
land = [[1, 4, 8, 10], [5, 5, 5, 5], [10, 10, 10, 10], [10, 10, 10, 20]]
height = 3
solution(land, height)
|
cs |
'알고리즘' 카테고리의 다른 글
[BOJ] 12016 가장 긴 증가하는 부분수열 - 이분탐색 (0) | 2020.10.29 |
---|---|
[BOJ] 9251 LCS - DP, 문자열 (0) | 2020.10.29 |
[Baekjoon] 친구 네트워크(Union Find) (0) | 2020.09.24 |
[Programmers] 등굣길(DP) (0) | 2020.09.23 |
[Programmers] 정수 삼각형(DP) (0) | 2020.09.23 |