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 |
Tags
- 그래프
- 분할 정복
- BFS
- 트리
- CI/CD
- HTTP
- 분할정복
- dfs
- TCP
- 알고리즘
- 그리드 알고리즘
- 자료구조
- 다이나믹 프로그래밍
- 컴퓨터 네트워크
- 그리드
- 스프링
- 브루트포스
- 재귀
- 역방향 반복자
- 백준
- 순열
- GIT
- 이분탐색
- SQL
- Spring
- 다이나믹프로그래밍
- 도커
- github action
- 자바
- AWS
Archives
- Today
- Total
코딩성장스토리
백준 2146번:다리 만들기 본문
https://www.acmicpc.net/problem/2146
2146번: 다리 만들기
여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다
www.acmicpc.net
이 문제는 각 섬마다 그룹화가 필요하다. 그 이유는 최단 거리를 구하기 위해서 DFS를 이용해야 하는데 그냥 돌려버리면
최단거리가 아닌 각 섬에서 출발하여 중간에서 만나는 거리가 구해지기 때문이다. 즉 섬마다 그룹을 나눈다음에 각 섬끼리의 최단거리를 각각 구해야한다.
즉 이 문제는 DFS를 각 섬의 개수만큼 돌려서 최단거리를 구하면 된다.
#include<iostream>
#include <queue>
#include <cstdio>
using namespace std;
#pragma warning(disable : 4996)
int px[4] = { 0,0,1,-1 };
int py[4] = { 1,-1,0,0 };
int d[100][100]; //값 넣기
int sum[100][100]; //BFS를 진행할때 거리 계산할 용도
int grp[100][100]; //그룹화를 할 배열
int cnt = 1; //섬의 그룹번호 지정을 위한 변수
int m;
void dfs(int x, int y) { //섬의 그룹화를 위한 dfs
grp[x][y] = cnt;
for (int k = 0; k < 4; k++) {
int nx = x + px[k];
int ny = y + py[k];
if (0 <= nx && nx < m && 0 <= ny && ny < m) {
if (grp[nx][ny] == 0 && d[nx][ny] == 1) {
dfs(nx, ny);
}
}
}
}
int main() {
cin >> m;
for (int i = 0; i < m; i++) {
for (int k = 0; k < m; k++) {
scanf("%1d", &d[i][k]);
}
}
for (int i = 0; i < m; i++) { //그룹번호 지정
for (int k = 0; k < m; k++) {
if (grp[i][k] == 0 && d[i][k] == 1) {
dfs(i, k);
cnt++;
}
}
}
int ans = -1;
for (int l = 1; l < cnt; l++) {
queue<pair<int, int>> q;
for (int i = 0; i < m; i++) {
for (int k = 0; k < m; k++) {
sum[i][k] = -1; //섬이 아니면 -1대입
if (grp[i][k] == l) {
sum[i][k] = 0; //섬이면 0대입
q.push(make_pair(i, k));
}
}
}
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + px[i];
int ny = y + py[i];
if (0 <= nx && nx < m && 0 <= ny && ny < m) { //한개의 섬을 기준으로 모든 거리 값 구하기
if (sum[nx][ny] == -1) {
sum[nx][ny] = sum[x][y] + 1;
q.push(make_pair(nx, ny));
}
}
}
}
for (int i = 0; i < m; i++) {
for (int k = 0; k < m; k++) {
if (d[i][k] == 1 && grp[i][k] != l) { //섬이면서 다른 섬인경우
if ((ans == -1) || (sum[i][k] - 1 < ans)) { //최단거리 구하기
ans = sum[i][k] - 1;
}
}
}
}
}
cout << ans;
return 0;
}
'백준 코딩' 카테고리의 다른 글
백준 11725번: 트리의 부모 찾기 (0) | 2021.10.18 |
---|---|
백준 1991번:트리 순회 (0) | 2021.10.11 |
백준2178번:미로 탐색 (0) | 2021.10.08 |
백준 2667번:단자번호붙이기 (0) | 2021.10.07 |
백준:9466번 팀 프로젝트 (0) | 2021.10.06 |