일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- #알고리즘 #백준 #1793 #백준1793 #algorithm #baekjoon #baekjoon1793 #C++
- #알고리즘 #백준 #1987 #백준1987 #algorithm #baekjoon #baekjoon1987 #Java
- #알고리즘 #백준 #17837 #백준17837 #algorithm #baekjoon #baekjoon17837 #C++
- 개발서
- #알고리즘 #algorithm #프로그래머스 #2020카카오공채 #블록이동하기 #programmers #C++
- #알고리즘 #백준 #4386 #백준4386 #algorithm #baekjoon #baekjoon4386 #C++
- 책리뷰
- 개발자취미
- #알고리즘 #algorithm #프로그래머스 #2020카카오공채 #외벽점검 #programmers #C++
- #알고리즘 #백준 #1525 #백준1525 #algorithm #baekjoon #baekjoon1525 #C++
- #알고리즘 #백준 #17472 #백준17472 #algorithm #baekjoon #baekjoon17472 #C++
- #알고리즘 #백준 #2352 #백준2352 #algorithm #baekjoon #baekjoon2352 #C++
- #알고리즘 #백준 #17140 #백준17140 #algorithm #baekjoon #baekjoon17140 #C++
- #알고리즘 #백준 #3190 #백준3190 #algorithm #baekjoon #baekjoon3190 #C++
- #알고리즘 #백준 #15683 #백준15683 #algorithm #baekjoon #baekjoon15683 #C++
- #알고리즘 #백준 #2580 #백준2580 #algorithm #baekjoon #baekjoon2580 #Java
- 스레드 #동시성 #thread #process #
- #알고리즘 #백준 #2573 #백준2573 #algorithm #baekjoon #baekjoon2573 #C++
- #알고리즘 #백준 #17136 #백준17136 #algorithm #baekjoon #baekjoon17136 #C++
- #알고리즘 #백준 #1260 #백준1260 #algorithm #baekjoon #baekjoon1260 #Java
- #알고리즘 #algorithm #프로그래머스 #2020카카오공채 #문자열압축 #programmers #C++
- #알고리즘 #백준 #14888 #백준14888 #algorithm #baekjoon #baekjoon14888 #C++
- 클린코드
- #알고리즘 #백준 #5214 #백준5214 #algorithm #baekjoon #baekjoon5214 #C++
- #알고리즘 #백준 #12094 #백준12094 #algorithm #baekjoon #baekjoon12094 #C++
- #알고리즘 #백준 #2616 #백준2616 #algorithm #baekjoon #baekjoon2616 #Java
- #알고리즘 #백준 #17406 #백준17406 #algorithm #baekjoon #baekjoon17406 #C++
- CleanCode
- #알고리즘 #백준 #15684 #백준15684 #algorithm #baekjoon #baekjoon15684 #C++
- #알고리즘 #algorithm #프로그래머스 #2020카카오공채 #괄호변환 #programmers #C++
Archives
- Today
- Total
개발자 일기장.
백준 17472. 다리만들기2 본문
다리만들기2
Problem?
문제.
Solution
- bfs를 통해 각 섬에 번호를 붙인다
- 완전 탐색을 통해 다리를 만든다.
- kruskal algorithm을 통한 MST를 만든다.
- 모두 연결된 경우에 한해서 출력하고 그 외에는 -1을 출력한다.
Code
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 100
#define K_MAX 6 + 1
pair<int, int> dir[4] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
int N, M, label = 0;
int board[MAX][MAX];
bool visited[MAX][MAX];
int k_board[K_MAX][K_MAX];
int parent[K_MAX];
vector<pair<int, pair<int, int>>> graph;
int answer = 0;
void bfs(int y, int x, int label) {
queue<pair<int, int>> q;
q.push({ y, x });
board[y][x] = label;
visited[y][x] = true;
while (!q.empty()) {
int curY = q.front().first;
int curX = q.front().second;
q.pop();
for (int d = 0; d < 4; d++) {
int nextY = curY + dir[d].first;
int nextX = curX + dir[d].second;
if (0 <= nextY && nextY < N && 0 <= nextX && nextX < M) {
if (!visited[nextY][nextX] && board[nextY][nextX]) {
q.push({ nextY, nextX });
board[nextY][nextX] = label;
visited[nextY][nextX] = true;
}
}
}
}
}
void make_bridge(int y, int x) {
int graph_id = board[y][x];
for (int d = 0; d < 4; d++) {
int cnt = 0;
while (true) {
int nextY = y + dir[d].first * (cnt + 1);
int nextX = x + dir[d].second * (cnt + 1);
if (0 > nextY || nextY >= N || 0 > nextX || nextX >= M)
break;
else if (board[nextY][nextX] == graph_id)
break;
else if (board[nextY][nextX] == 0) {
cnt++;
continue;
}
else {
if (cnt >= 2) {
int graph_id2 = board[nextY][nextX];
if (k_board[graph_id][graph_id2]) {
k_board[graph_id][graph_id2] = min(cnt, k_board[graph_id][graph_id2]);
k_board[graph_id2][graph_id] = min(cnt, k_board[graph_id][graph_id2]);
}
else {
k_board[graph_id][graph_id2] = cnt;
k_board[graph_id2][graph_id] = cnt;
}
}
break;
}
}
}
}
int collapsingFind(int n) {
int root;
for (root = n; parent[root] >= 1; root = parent[root]);
for (int i = n; i != root; i = parent[i])
parent[i] = root;
return root;
}
void weightedUnion(int i, int j) {
int temp = parent[i] + parent[j];
if (parent[i] > parent[j]) {
parent[i] = j;
parent[j] = temp;
}
else {
parent[j] = i;
parent[i] = temp;
}
}
void kruskal() {
for (int i = 1; i <= label; i++)
for (int j = i; j <= label; j++)
if (k_board[i][j])
graph.push_back(make_pair(k_board[i][j], make_pair(i, j)));
sort(graph.begin(), graph.end());
for (int i = 1; i <= label; i++)
parent[i] = -1;
for (int i = 0; i < graph.size(); i++) {
int p = collapsingFind(graph[i].second.first);
int q = collapsingFind(graph[i].second.second);
if (p != q) {
weightedUnion(p, q);
answer += graph[i].first;
}
}
}
bool isAllConnected() {
bool flag = false;
for (int i = 1; i <= label; i++) {
if (parent[i] == -1)
return false;
if (parent[i] < -1) {
if (flag) // 제일 큰 부모는 하나만 있어야한다.
return false;
flag = true;
}
}
return true;
}
int main(int argc, const char* argv[]) {
// input
cin >> N >> M;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
scanf("%d", &board[i][j]);
// solution 1 - bfs
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (!visited[i][j] && board[i][j]) {
label++;
bfs(i, j, label);
}
// solution 2 - make bridge
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (board[i][j])
make_bridge(i, j);
// solution 3 - kruskal
kruskal();
// output
if (isAllConnected())
cout << answer << "\n";
else
cout << "-1\n";
return 0;
}
collapsingFind와 weightedUnion을 사용했다.
'취업 > Algorithm.' 카테고리의 다른 글
백준 17140. 이차원배열과 연산 (0) | 2020.04.11 |
---|---|
백준 15684. 사다리 조작 (0) | 2020.04.11 |
백준 17406. 배열 돌리기4 (0) | 2020.03.28 |
[2020 카카오 공채] 블록 이동하기 (0) | 2020.03.22 |
[2020 카카오 공채] 문자열 압축 (0) | 2020.03.22 |