Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 크루스칼
- 다익스트라
- 로봇 청소기
- 구현
- Spring
- 시뮬레이션
- 프로그래머스
- 우선순위큐
- 플로이드와샬
- 조합
- 트라이
- 플로이드 와샬
- 브루트포스
- BFS
- 최소 신장 트리
- 2020 카카오 인턴십
- SWEA
- 백준
- GIT
- 2019 KAKAO BLIND RECRUITMENT
- 2020 KAKAO BLIND RECRUITMENT
- 백트래킹
- 2018 KAKAO BLIND RECRUITMENT
- 파이썬
- 투포인터
- 비트마스킹
- 스택
- 이분탐색
- 2021 KAKAO BLIND RECRUITMENT
- 투 포인터
Archives
- Today
- Total
개발조아
[BOJ/백준] 17472 다리 만들기 2 파이썬 본문
728x90
문제 링크 : https://www.acmicpc.net/problem/17472
예전에 풀었던 걸 MST로 다시 풀어봤다.
예전에는 BFS,DFS로 완탐으로 해결했었다.
이번에는 BFS, MST로 해결했다.
BFS로 각 섬에 번호 매기면서 섬의 가장자리를 구한다.
이때 해당 점에서 이동하려는 점이 격자판 안에 있고 물인 경우 가장자리로 판별해서 저장했다.
(x,y,방향) 이때 방향은 해당 칸으로 온 방향이다.
구한 가장자리에서 다리를 만들면서 유효한 다리 정보를 생성한다.
이때는 구한 가장자리의 정보를 가지고 다리를 생성한다.
저장한 방향정보 가지고 범위를 벗어나거나 다른 섬을 만날때까지 진행한다.
다른 섬을 만났다면 다리 정보를 생성하자.
(출발 다리 번호, 도착 다리 번호, 길이)
다음 다리 정보를 길이순으로 오름차순해서 정렬한 후 MST에 사용하자
마지막 MST는 크루스칼을 이용했다.
from sys import stdin
from collections import deque
input = stdin.readline
dx = [-1,1,0,0]
dy = [0,0,-1,1]
n,m = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]
edges = []
def solv():
global parent
max_num = set_area_num()
parent = [i for i in range(max_num)]
candidate_bridge = set_candidate_bridge()
print(kruskal(candidate_bridge,max_num))
def kruskal(candidate_bridge, max_num):
bridge_count = 0
length = 0
for a,b,c in candidate_bridge:
if not is_same_parent(a,b):
union(a,b)
bridge_count += 1
length += c
if bridge_count == max_num-3:
return length
return -1
def find(target):
global parent
if parent[target] == target:
return target
parent[target] = find(parent[target])
return parent[target]
def union(a,b):
global parent
a = find(a)
b = find(b)
if a != b:
if a > b:
parent[a] = b
else:
parent[b] = a
def is_same_parent(a,b):
return find(a) == find(b)
def set_candidate_bridge():
candidate_bridge = set()
for x,y,d in edges:
start = board[x][y]
length = 0
while True:
x += dx[d]
y += dy[d]
if boundaray_validator(x,y):
end = board[x][y]
if end != 0:
if start != end and length >= 2:
candidate_bridge.add((start,end,length))
break
length += 1
else:
break
candidate_bridge = sorted(candidate_bridge, key=lambda x:x[2])
return candidate_bridge
def set_area_num():
num = 2
for x in range(n):
for y in range(m):
if board[x][y] == 1:
bfs(x,y,num)
num += 1
return num
def bfs(sx,sy,num):
global board,edges
q = deque([(sx,sy)])
board[sx][sy] = num
while q:
x,y = q.pop()
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if boundaray_validator(nx,ny):
if board[nx][ny] == 1:
board[nx][ny] = num
q.appendleft((nx,ny))
elif board[nx][ny] == 0:
edges.append((x,y,d))
def boundaray_validator(x,y):
if x < 0 or y < 0 or x >= n or y >= m:
return False
return True
solv()
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 1553 도미노 찾기 파이썬 (0) | 2021.12.06 |
---|---|
[BOJ/백준] 23034 조별과제 멈춰! 파이썬 (0) | 2021.12.05 |
[BOJ/백준] 2479 경로 찾기 파이썬 (0) | 2021.12.03 |
[BOJ/백준] 1944 복제 로봇 (0) | 2021.12.03 |
[BOJ/백준] 5670 휴대폰 자판 파이썬 (0) | 2021.11.06 |
Comments