반응형
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
- OFFSET
- 매개변수탐색
- 처우산정
- @P0
- 퇴사통보
- 연결요소
- 백트래킹
- 물채우기
- incr
- Kafka
- 파라메트릭
- BOJ
- 기술면접
- softeer
- boj #19237 #어른 상어
- upper_bound
- Docker
- 백준
- 13908
- 소프티어
- 처우협의
- 오퍼레터
- BFS
- 6987
- compose
- 경력
- 성적평가
- msSQL
- 이분탐색
- dfs
Archives
- Today
- Total
기술 블로그
지형 이동 본문
728x90
반응형
https://programmers.co.kr/learn/courses/30/lessons/62050
programmers 프로그래머스 최소신장트리 mst sw역량테스트 코딩 코테 복습 구현 생각 필수
java 자바 collections Collections 컬렉션 java vector sort 자바 프로그래머스 유니온 파인드
처음에 bfs로 접근하려다가, 순간 최소신장트리(mst) 문제임을 알았다.(아래의 문제를 풀었기 때문)
비슷한 문제 : https://hsdevelopment.tistory.com/416
나는 사이클 여부를 union-find를 활용하였다.
연결된 다리의 개수는 전체 정점의 개수 - 1 이어야만 한다.
참고로 Java에서 몇 개 틀렸었는데, p 배열을 초기화 할 때, 연결요소의 개수가 N+1개 이상일 수도 있다.
그래서 넉넉하게 N * N + N으로 초기화했다.
또한, 정렬할 때 C++에서는 단순 거리(first)로만 정렬했는데도 정답이었으나
Java에서는 틀리게 나왔었다. 그래서 Java에서는 second, third 모두 오름차순 정렬해줬다.
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 | #include <bits/stdc++.h> using namespace std; #define Max 303 typedef struct info { int from, to, distance; }info; int dy[4] = { 0, 1, 0, -1 }; int dx[4] = { 1, 0, -1, 0 }; int p[Max * Max], m[Max][Max], R, C; vector<vector<int> > v; vector<info> d; bool visit[Max][Max]; bool cmp(const info & a, const info & b) { return a.distance < b.distance; } int Find(int x) { if (x == p[x]) { return x; } return p[x] = Find(p[x]); } void Union(int a, int b) { a = Find(a); b = Find(b); if (a < b) { p[b] = a; } else { p[a] = b; } } void dfs(int r, int c, int group, int h) { visit[r][c] = true; m[r][c] = group; for (int i = 0; i < 4; i++) { int y = r + dy[i]; int x = c + dx[i]; if (y < 0 || y >= R || x < 0 || x >= C || visit[y][x] || abs(v[r][c] - v[y][x]) > h) { continue; } dfs(y, x, group, h); } } int solution(vector<vector<int> > land, int height) { int answer = 0; R = land.size(); C = R; v = land; int idx = 1; for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { p[i*C + j + 1] = i*C + j + 1; // Union-Find if (!visit[i][j]) { // 그룹화 dfs(i, j, idx, height); ++idx; } } } // 정점에서 다른 정점으로 사다리 타는 최소 비용 후보들을 d vector에 push_back for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { for (int k = 0; k < 4; k++) { int y = i + dy[k]; int x = j + dx[k]; if (y < 0 || y >= R || x < 0 || x >= C || m[i][j] == m[y][x]) { continue; } int f = m[i][j], t = m[y][x]; // 따로 최솟값을 구하는 과정을 안 거쳐도 그냥 d vector에 push_back -> 그 후 정렬 d.push_back({ f, t, abs(land[i][j] - land[y][x]) }); } } } sort(d.begin(), d.end(), cmp); // 정렬 int con = 0; for (auto i : d) { if (Find(i.from) != Find(i.to)) { Union(i.from, i.to); answer += i.distance; if (++con == idx - 2) { break; } } } return answer; } int main() { cin.tie(0); vector<vector<int> > v = { { 1, 4, 8, 10 }, { 5, 5, 5, 5 }, { 10, 10, 10, 10 }, { 10, 10, 10, 20 } }; //vector<vector<int> > v = { // { 10, 11, 10, 11 }, // { 2, 21, 20, 10 }, // { 1, 20, 21, 11 }, // { 2, 1, 2, 1 } // // 답 2 //}; printf("%d\n", solution(v, 3)); return 0; } | cs |
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 154 155 156 157 | import java.io.*; import java.util.*; public class Solution { static boolean[][] visit; static int[][] group, Land; static int N; static int[] dy = {0, 1, 0, -1}, dx = {1, 0, -1, 0}, p; static Vector<info> v; static BufferedReader br; static BufferedWriter bw; static int Find(int x) { if(x==p[x]) return x; return p[x] = Find(p[x]); } static void Union(int a, int b) { a = Find(a); b = Find(b); if(a < b) { p[b] = a; } else { p[a] = b; } } static void dfs(int r, int c, int height, int gn) { group[r][c] = gn; visit[r][c] = true; for(int i=0; i<4; i++) { int y = r + dy[i]; int x = c + dx[i]; if(y < 0 || y >= N || x < 0 || x >= N || visit[y][x] || Math.abs(Land[r][c] - Land[y][x]) > height) { continue; } dfs(y, x, height, gn); } } public static int solution(int[][] land, int height) { int answer = 0; N = land.length; Land = land; group = new int[N+3][N+3]; visit = new boolean[N+3][N+3]; p = new int[N*N + N]; v = new Vector<info>(); for(int i=0; i<=N; i++) { Arrays.fill(group[i], 0); Arrays.fill(visit[i], false); } int gn = 1; for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { p[i*N + j + 1] = i*N + j + 1; if(!visit[i][j]) { dfs(i, j, height, gn); ++gn; } } } --gn; for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { for(int k=0; k<4; k++) { int y = i + dy[k]; int x = j + dx[k]; if(y < 0 || y >= N || x < 0 || x >= N || group[i][j] == group[y][x]) { continue; } v.add(new info(Math.abs(land[i][j] - land[y][x]), group[i][j], group[y][x])); } } } Collections.sort(v, new Comparator<info>() { public int compare(info p1, info p2) { if(p1.first < p2.first) { return -1; // 오름차순 } else if(p1.first == p2.first) { if(p1.second < p2.second) { return -1; } else if(p1.second == p2.second) { if(p1.third < p2.third) { return -1; } } } return 1; } }); int cnt = 0; for(info i : v) { if(Find(i.second) != Find(i.third)) { Union(i.second, i.third); answer += i.first; if(++cnt == gn - 1) { break; } } } return answer; } public static void main(String[] args) { // TODO Auto-generated method stub br = new BufferedReader(new InputStreamReader(System.in)); bw = new BufferedWriter(new OutputStreamWriter(System.out)); StringTokenizer st; int[][] land = { { 10, 11, 10, 11 }, { 2, 21, 20, 10 }, { 1, 20, 21, 11 }, { 2, 1, 2, 1 } }; System.out.println(solution(land, 1)); // bw.write(String.valueOf(answer) + "\n"); // bw.flush(); // bw.close(); } } class info { int first, second, third; info(int a, int b, int c) { this.first = a; this.second = b; this.third = c; } } | cs |
728x90
반응형