반응형
1. 신장트리 : 그래프의 모든 정점과 간선의 부분집합으로 구성되는 트리
2. 최소신장트리(MST) : 신장트리 중에서 사용된 간선들의 가중치 합이 최소인 트리
- 무방향 가중치 그래프
- 그래프의 가중치의 합이 최소여야 한다.
- N개의 정점을 가지는 그래프에 대해 반드시 (N-1) 개의 간선을 사용해야 한다.
- 사이클을 포함해서는 안된다.
3. Kruskal Algorithm
- 탐욕적인 방법을 이용하여 가중그래프(가중치를 간선에 할당한 그래프)의 모든 정점을 최소비용으로 연결하는 최적해를 구하는 것
- 간선을 하나씩 선택해서 MST를 찾는 알고리즘
- 동작과정
① 그래프의 간선들을 가중치의 오름차순으로 정렬한다.
② 정렬된 간선 리스트에서 순서대로 사이클을 형성하지 않는 간선을 선택한다.
a. 가중치가 가장 낮은 간선을 선택한다.
b. 사이클이 형성되면 다음 간선을 선택
③ 해당 간선을 MST 집합에 추가한다. (정점의수-1)개의 간선이 선택될때 까지 반복
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Kruskal {
static int[] parents;
static int[] rank;
// 입력은 첫줄에 정점의 갯수와 간선의 갯수가 들어오고
// 그 다음줄부터 간선의 정보가 정점1 정점2 가중치로 간선의 갯수만큼 들어옴
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int V = sc.nextInt();
int E = sc.nextInt();
parents = new int[V];
rank = new int[V];
int[][] edges = new int[E][3];
for(int i=0; i<E; i++) {
edges[i][0] = sc.nextInt(); // 정점1
edges[i][1] = sc.nextInt(); // 정점2
edges[i][2] = sc.nextInt(); // 가중치
}
// 간선들의 가중치 오름차순 정렬
Arrays.sort(edges, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// o1[2] o2[2]
return Integer.compare(o1[2], o2[2]);
}
});
// 각 정점에 대해 유니온파인드 연산 준비.
for(int i=0; i<V; i++) makeSet(i);
int result=0;
int cnt = 0;
for(int i=0; i<V-1; i++) {
int a = findSet(edges[i][0]);
int b = findSet(edges[i][1]);
if(a==b) continue;
union(a, b);
// 간선을 선택.
result += edges[i][2];
// 정점의 갯수 -1번 반복하면 그만
cnt++;
if(cnt == V-1) break;
}
System.out.println(result);
// 간선이 연결하는 두 정점이 같은 팀이 아니라면 한 팀으로 합쳐주고 간선 선택
// 같은팀이라면 패스
}
static void makeSet(int x) {
parents[x] = x;
}
static int findSet(int x) {
if(x == parents[x]) return x;
else {
parents[x] = findSet(parents[x]);
return findSet(parents[x]);
}
}
static void union(int x, int y) {
int px = findSet(x);
int py = findSet(y);
if( rank[px] > rank[py] ) {
parents[py] = px;
} else {
parents[px] =py;
if(rank[px] == rank[py]) {
rank[py]++;
}
}
}
}
반응형
'알고리즘 > 이론' 카테고리의 다른 글
서로소 집합(Disjoint-set) (0) | 2020.04.19 |
---|---|
프림 알고리즘 (Prim Algorithm) (0) | 2020.04.19 |
순열 (Permutation) (0) | 2019.04.11 |
크루스칼 알고리즘 (Kruskal's Algorithm) (0) | 2019.03.09 |
다익스트라 알고리즘 (Dijkstra's Algorithm) (0) | 2019.03.09 |