일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- hash
- toUpperCase
- append
- dp
- replace()
- 백준 2467번 용액 자바 - 이분탐색
- 백준 2473번 세 용액 - java
- 백준 14938번 서강그라운드
- 백준 1647번 도시 분할 계획 - java
- 프로그래머스
- kotlin
- 백준 1197번 최소 스패닝 트리 - java
- Stack
- Java
- StringTokenizer
- 18111번 마인크래프트 - java 구현
- ac 5430번
- StringBuilder
- 백준 3190번
- 프로그래머스 자바
- 프로그래머스 java
- mysql hy000 에러
- 백준 1806번 부분합 java
- 백준 1541
- HashSet
- 백준 1043번 거짓말 - java 분리 집합
- 코틀린기초
- 최소 힙 1927
- HashMap
- map
Archives
- Today
- Total
말하는 컴공감자의 텃밭
백준 1197번 최소 스패닝 트리 - Java 본문
728x90
최소 스패닝 트리
최소 스패닝 기본 문제이다.
모든 정점이 연결되어야 하고, 각 연결된 간선이 최소값으로만 구성이 되어야 한다.
크루스칼과 프림 알고리즘으로 해결할 수 있는데, 두가지로 풀어보았다.
🔽 알고리즘 차이점 확인
https://hb-in99.tistory.com/191
최소 신장 트리를 위한 프림, 크루스칼 알고리즘
정점과 가중치가 존재하는 간선이 주어진 상태에서 우리는 모든 정점을 가장 적은 비용으로 연결한 그래프를 최소 신장 트리라고 말한다. MST(Minimum Spanning Tree) 라고 말하며 이러한 문제에서 사
hb-in99.tistory.com
프림 알고리즘
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 | import java.io.*; import java.util.*; public class Main { // 최소 스패닝 트리 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int V = Integer.parseInt(st.nextToken()); int E = Integer.parseInt(st.nextToken()); // 간선이 아닌 정점의 개수로 변경.. ArrayList<Node>[] tree = new ArrayList[V + 1]; boolean[] visited = new boolean[V + 1]; for (int i = 1; i <= V; i++) { tree[i] = new ArrayList<>(); } for (int i = 0; i < E; i++) { st = new StringTokenizer(br.readLine()); int s = Integer.parseInt(st.nextToken()); int e = Integer.parseInt(st.nextToken()); int c = Integer.parseInt(st.nextToken()); tree[s].add(new Node(e, c)); tree[e].add(new Node(s, c)); } PriorityQueue<Node> pq = new PriorityQueue<>(); pq.add(new Node(1, 0)); long answer = 0L; while (!pq.isEmpty()) { Node node = pq.poll(); if (visited[node.idx]) { continue; } answer += node.cost; visited[node.idx] = true; for (Node next : tree[node.idx]) { if (!visited[next.idx]) { pq.add(new Node(next.idx, next.cost)); } } } System.out.println(answer); } public static class Node implements Comparable<Node> { int idx; int cost; public Node(int idx, int cost) { this.idx = idx; this.cost = cost; } @Override public int compareTo(Node n1) { return Integer.compare(this.cost, n1.cost); } } } | 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 | import java.io.*; import java.util.*; public class Main { // 최소 스패닝 트리 - 크루스칼 알고리즘 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int V = Integer.parseInt(st.nextToken()); int E = Integer.parseInt(st.nextToken()); PriorityQueue<Node> pq = new PriorityQueue<>(); for (int i = 0; i < E; i++) { st = new StringTokenizer(br.readLine()); int s = Integer.parseInt(st.nextToken()); int e = Integer.parseInt(st.nextToken()); int c = Integer.parseInt(st.nextToken()); pq.add(new Node(s, e, c)); // } int[] parent = new int[V + 1]; int[] rank = new int[V + 1]; for (int i = 1; i <= V; i++) { parent[i] = i; rank[i] = 1; } long answer = 0L; int edgesUsed = 0; while (edgesUsed < V - 1 && !pq.isEmpty()) { Node node = pq.poll(); if (union(parent, rank, node.start, node.end)) { answer += node.weight; edgesUsed++; } } System.out.println(answer); } // Find 연산 경로 압축 기법 public static int find(int[] parent, int x) { if (parent[x] != x) { parent[x] = find(parent, parent[x]); } return parent[x]; } // Union 연산 랭크를 활용하여 트리 높이를 최소화 public static boolean union(int[] parent, int[] rank, int a, int b) { int rootA = find(parent, a); int rootB = find(parent, b); if (rootA == rootB) return false; // 이미 같은 집합에 속하는 경우 // 랭크를 기준으로 낮은 트리를 높은 트리 아래에 붙임 if (rank[rootA] > rank[rootB]) { parent[rootB] = rootA; } else if (rank[rootA] < rank[rootB]) { parent[rootA] = rootB; } else { parent[rootB] = rootA; rank[rootA]++; } return true; } public static class Node implements Comparable<Node> { int start; int end; int weight; public Node(int start, int end, int weight) { this.start = start; this.end = end; this.weight = weight; } @Override public int compareTo(Node n) { return Integer.compare(this.weight, n.weight); // 가중치에 따라 비교 } } } | cs |
728x90
'알고리즘 > Backjoon - Java' 카테고리의 다른 글
백준 1043번 거짓말 - Java 분리 집합 (0) | 2024.08.30 |
---|---|
백준 2473번 세 용액 - Java 이분탐색 (0) | 2024.08.29 |
백준 18111번 마인크래프트 - Java 구현 (0) | 2024.08.27 |
백준 1647번 도시 분할 계획 - Java 최소 스패닝 트리 (0) | 2024.08.26 |
백준 1806번 부분합 - Java 투 포인터 (0) | 2024.08.21 |
Comments