본문 바로가기
카테고리 없음

백준 2146 다리만들기

by zieunee 2020. 1. 27.
반응형

acmicpc.net/problem/2146

 

2146번: 다리 만들기

여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다는 생각을 하게 되었다. 그래서 그는, 생색내는 식으로 한 섬과 다른 섬을 잇는 다리 하나만을 만들기로 하였고, 그 또한 다리를 가장 짧게 하여 돈을 아끼려 하였다. 이 나라는 N×N크기의 이차원 평면상에 존재한다. 이 나라는 여러 섬으로 이루어져 있으며, 섬이란 동서남북

www.acmicpc.net

단지번호 붙이기 + 짧은 다리 만들기 dfs + bfs 

 

#define CRT_SECURE_NO_WARNING
#include<iostream>
#include<queue>
#include<algorithm>	

using namespace std;
int map[101][101];
int N;
int islandNum = 2;
int dy[4] = { 1,0,-1,0 };
int dx[4] = { 0,1,0,-1 };
int res=987654321;

void dfs(int x, int y, int num) {
	map[x][y] = num;
	for (int i = 0; i < 4; i++) {
		int cx = x + dx[i];
		int cy = y + dy[i];
		if (cx < 0 || cy < 0 || cx >= N || cy >= N || map[cx][cy] != 1) continue;
		dfs(cx, cy, num);
	}
}

int bfs(int x, int y, int num) {
	queue <pair<pair<int, int>, int>> q;
	q.push({ {x,y},0 });
	int visited[101][101] = { 0, };
	while (!q.empty()) {
		int nx = q.front().first.first;
		int ny = q.front().first.second;
		int cnum = q.front().second;
		q.pop();

		for (int i = 0; i < 4; i++) {
			int cx = nx + dx[i];
			int cy = ny + dy[i];
			if (cx < 0 || cy < 0 || cx >= N || cy >= N || map[cx][cy] == num || visited[cx][cy] == 1) continue;
			if (map[cx][cy] != 0) return cnum;
			visited[cx][cy] = 1;
			q.push({ {cx,cy},cnum+1 });
		}
	}
	return 987654321;
}

int main() {
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			scanf("%d", &map[i][j]);
		}
	}

	//단지번호 붙이기
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (map[i][j] == 1) {
				dfs(i, j, islandNum);
				islandNum++;
			}
		}
	}

	//짧은 다리 만들기

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (map[i][j] != 0) {	
				res = min(res, bfs(i, j, map[i][j]));
			}
		}
	}

	printf("%d", res);
	return 0;

}

 

반응형