코드와이
[BAEKJOON] 17472. 다리 만들기2 본문
BFS
DFS
최소 신장 트리
그래프 탐색
문제링크
17472번: 다리 만들기 2
첫째 줄에 지도의 세로 크기 N과 가로 크기 M이 주어진다. 둘째 줄부터 N개의 줄에 지도의 정보가 주어진다. 각 줄은 M개의 수로 이루어져 있으며, 수는 0 또는 1이다. 0은 바다, 1은 땅을 의미한다.
www.acmicpc.net
package acmicpc.Gold2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 다리_만들기2 {
static int n, m, cnt;
static int[][] map;
static int[] dr = {1,0,-1,0};
static int[] dc = {0,1,0,-1};
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map = new int[n][m];
for(int i = 0 ; i < n ; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < m ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
cnt = 2;
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
if(map[i][j] == 1) change(i,j,cnt++);
}
}
cnt -= 2;
int[][] adj = new int[cnt][cnt];
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
if(map[i][j] != 0) {
for(int d = 0 ; d < 4 ; d++) {
int nr = i + dr[d];
int nc = j + dc[d];
int sum = 0;
int start = map[i][j] - 2;
int dest = 0;
while(nr >= 0 && nc >= 0 && nr < n && nc < m) {
if(map[nr][nc] != 0) {
dest = map[nr][nc];
break;
}
nr += dr[d];
nc += dc[d];
sum++;
}
dest -= 2;
if(sum > 1 && dest != -2) {
if(adj[start][dest] > 0) {
adj[start][dest] = Math.min(adj[start][dest], sum);
} else {
adj[start][dest] = sum;
}
adj[dest][start] = adj[start][dest];
}
}
}
}
}
boolean[] visited = new boolean[cnt];
int[] minEdge = new int[cnt];
for(int i = 0 ; i < cnt ; i++) {
minEdge[i] = Integer.MAX_VALUE;
}
int minIdx, min, ans = 0;
minEdge[0] = 0;
for(int x = 0 ; x < cnt ; x++) {
min = 987654321;
minIdx = -1;
for(int i = 0 ; i < cnt ; i++) {
if(!visited[i] && min > minEdge[i]) {
min = minEdge[i];
minIdx = i;
}
}
if(minIdx == -1) {
ans = -1;
break;
}
ans += min;
visited[minIdx] = true;
for(int i = 0 ; i < cnt ; i++) {
if(!visited[i] && adj[minIdx][i] != 0 && minEdge[i] > adj[minIdx][i]) {
minEdge[i] = adj[minIdx][i];
}
}
}
System.out.println(ans);
}
private static void change(int r, int c, int x) {
map[r][c] = x;
for(int d = 0 ; d < 4 ; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if(nr < 0 || nc < 0 || nr >= n || nc >= m) continue;
if(map[nr][nc] == 1) {
change(nr, nc, x);
}
}
}
}
'acmicpc' 카테고리의 다른 글
[BAEKJOON] 1759. 암호 만들기 (0) | 2021.04.04 |
---|---|
[BAEKJOON] 1932. 정수 삼각형 (0) | 2021.03.27 |
[BAEKJOON] 14502. 연구소 (0) | 2021.03.26 |
[BAEKJOON] 2206. 벽 부수고 이동하기 (0) | 2021.03.25 |
[BAEKJOON] 11055. 가장 큰 증가 부분 수열 (0) | 2021.03.25 |