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
- 카카오
- BFS
- 투포인터
- 중반부
- 삼성 #코테 #2020상반기 #c++
- 백준
- LIS #Algorithm #요소추적
- Union-find
- 스마일게이트
- 알고리즘
- 서버개발캠프
- 식단
- 코테
- 보석쇼핑
- c++
- 소감
- BaekJoon
- Algorithm
- 코딩테스트
- 유니온파인드
- IBK기업은행 #기업은행 #디지털 #직무 #정리
- 1편
- 카카오인턴
- Smilegate
Archives
- Today
- Total
짱아의 개발 기록장
백준 17472번. 다리 만들기2(c++) / BFS+유니온파인드 본문
반응형
설명 추가 예정
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #include <iostream> #include <queue> #include <vector> #include <climits> #include <tuple> #include <algorithm> using namespace std; int n, m; int connect[7] = { 0, }; int map[11][11] = { 0, }; int dx[4] = { 0, 0, -1, 1 }; int dy[4] = { -1, 1, 0, 0 }; int check[11][11] = { 0, }; // 영역 표시하기 vector<pair<int, int>> edge[7]; int areaNum = 0; vector<int> seq; // 다리를 만드는 순서 int find(int i) { if (i == connect[i]) { return i; } return connect[i] = find(connect[i]); } int makeBridge() { int ans = 0; // 총 다리의 길이 // from -> to 를 잇는 다리 건설 for (int i = 0; i < seq.size(); i++) { int from = seq[i]; queue<tuple<int, int, int, int>> q; for (int k = 0; k < edge[from].size(); k++) { for (int t = 0; t < 4; t++) { q.push(make_tuple(edge[from][k].first, edge[from][k].second, 0, t)); } } while (!q.empty()) { int x, y, cnt, dir; tie(x, y, cnt, dir) = q.front(); q.pop(); int nx = x + dx[dir]; int ny = y + dy[dir]; if (0 <= nx && nx < n && 0 <= ny && ny < m && check[nx][ny] != from) { if (map[nx][ny] == 0) { q.push(make_tuple(nx, ny, cnt + 1, dir)); } else { //from -> to 다리를 이을 수 있으면 잇는다. int to = check[nx][ny]; int a = find(from); int b = find(to); if (a==b || cnt<2) continue; connect[a] = b; ans += cnt; } } } } return ans; } void makeArea() { int ans = INT_MAX; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 0) continue; if (check[i][j] != 0) continue; int visited[11][11] = { 0, }; areaNum++; queue<pair<int, int>> q; q.push(make_pair(i, j)); while (!q.empty()) { int x = q.front().first; int y = q.front().second; q.pop(); visited[x][y] = true; check[x][y] = areaNum; for (int k = 0; k < 4; k++) { int nx = x + dx[k]; int ny = y + dy[k]; if (0 <= nx && nx < n && 0 <= ny && ny < m && !visited[nx][ny]) { visited[nx][ny] = true; if (map[nx][ny] == 0) { edge[check[x][y]].push_back(make_pair(x, y)); } if (map[nx][ny] == 1) { q.push(make_pair(nx, ny)); } } } } } } } bool isAllConnect() { for (int i = 1; i < areaNum; i++) { if (find(i) != find(i + 1)) return false; } return true; } int main() { cin >> n>>m; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> map[i][j]; } } int ans = INT_MAX; bool isPossible = false; // 모든 섬을 연결하는 것이 가능한지 // 영역 표시 makeArea(); // Brute Force로 최단 다리 구하기 for (int i = 1; i <= areaNum; i++) { seq.push_back(i); } do { for (int i = 1; i <= areaNum; i++) { connect[i] = i; } int num = makeBridge(); if (isAllConnect()) { isPossible = true; ans = min(ans, num); } } while (next_permutation(seq.begin(), seq.end())); if (isPossible) { cout << ans << "\n"; } else { cout << "-1" << "\n"; } return 0; } | cs |
반응형
'Algorithm > Baekjoon' 카테고리의 다른 글
백준 9328번. 열쇠(c++) / BFS+비트마스크 (0) | 2021.03.30 |
---|---|
백준 2146번. 다리 만들기(c++) / BFS (0) | 2021.03.30 |
백준 17135번. 캐슬 디펜스(c++) / 구현 (0) | 2021.03.27 |
백준 16926번. 배열 돌리기1(c++) / 구현 (0) | 2021.03.25 |
백준 3190번. 뱀(c++) / 구현 (0) | 2021.03.16 |
Comments