최소 신장 트리(Minimum Spanning Tree , MST)
- 그래프 상의 모든 노드들을 최소 비용으로 연결하는 방법
크루스칼 (Kruskal)
- 간선 중 최소 값을 가진 간선부터 연결
- 사이클 발생 시 다른 간선 선택
- 주로 간선 수가 적을 때 사용
알고리즘 복잡도 : O(ElogE)
경로 최적화를 이용하지 않는 경우 O(ElogV), 경로 최적화를 이용하는 경우 O(Elog∗V)
프림(Prim)
- 임의의 노드에서 시작
- 연결된 노드들의 간선 중 낮은 가중치를 갖는 간선 선택
- 간선의 개수가 많을 때 쿠르스칼 보다 유리
알고리즘 복잡도 : O(ElogV)
바이너리 힙을 이용하는 경우 O(E+VlogV)
import java.util.Arrays;
//최소 신장 트리 - 크루스칼
public class kruskal {
static int parents[];
public static int kruskal(int[][] data, int v , int e){
int weightSum = 0;
Arrays.sort(data, (x, y) -> x[2] - y[2]);
parents = new int[v + 1];
for (int i = 1; i < v + 1; i++) {
parents[i] = i;
}
for (int i = 0; i < e; i++) {
if (find(data[i][0]) != find(data[i][1])){
union(data[i][0], data[i][1]);
weightSum += data[i][2];
}
}
return weightSum;
}
public static void union(int a, int b){
int aP = find(a);
int bP = find(b);
if (aP != bP) {
parents[aP] = bP;
}
}
public static int find(int a){
if (a == parents[a]){
return a;
}
return parents[a] = find(parents[a]);
}
public static void main(String[] args) {
int v = 7;
int e = 10;
int[][] graph = {{1, 3, 1}, {1, 2, 9}, {1, 6, 8}, {2, 4, 13}, {2, 5, 2}, {2, 6, 7}, {3, 4, 12}, {4, 7, 17}, {5, 6, 5}, {5, 7, 20}};
System.out.println(kruskal(graph, v, e));
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
//최소 신장 트리 - 프림
public class prim {
static class Node{
int to;
int weight;
public Node(int to, int weight){
this.to = to;
this.weight = weight;
}
}
public static int prim(int[][] data, int v , int e){
int weightSum = 0;
ArrayList<ArrayList<Node>> graph = new ArrayList<>();
for (int i = 0; i < v + 1; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < e; i++) {
graph.get(data[i][0]).add(new Node(data[i][1], data[i][2]));
graph.get(data[i][1]).add(new Node(data[i][0], data[i][2]));
}
boolean[] visited = new boolean[v + 1];
PriorityQueue<Node> pq = new PriorityQueue<>((x, y) -> x.weight - y.weight);
pq.add(new Node(1, 0));
int cnt = 0;
while (!pq.isEmpty()){
Node cur = pq.poll();
cnt += 1;
if (visited[cur.to]){
continue;
}
visited[cur.to] = true;
weightSum += cur.weight;
if (cnt == v){
return weightSum;
}
for (int i = 0; i < graph.get(cur.to).size() ; i++) {
Node adjNode = graph.get(cur.to).get(i);
if (visited[adjNode.to]){
continue;
}
pq.offer(adjNode);
}
}
return weightSum;
}
public static void main(String[] args) {
int v = 7;
int e = 10;
int[][] graph = {{1, 3, 1}, {1, 2, 9}, {1, 6, 8}, {2, 4, 13}, {2, 5, 2}, {2, 6, 7}, {3, 4, 12}, {4, 7, 17}, {5, 6, 5}, {5, 7, 20}};
System.out.println(prim(graph, v, e));
}
}
'Study for Backend > Algorithm' 카테고리의 다른 글
[Algorithm 기초] 백트랙킹 (Backtracking) (0) | 2024.03.17 |
---|---|
[Algorithm 기초 연습] 이진 탐색을 이용한 숫자 찾기 (2) | 2024.03.16 |
[Algorithm 기초] 최단 경로 알고리즘 (플로이드-워셜) (0) | 2024.03.06 |
[Algorithm 기초] 최단 경로 알고리즘 (벨만 포드) (2) | 2024.03.05 |
[Algorithm 기초] 최단 경로 알고리즘 (다익스트라) (0) | 2024.03.04 |