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 | 
													Tags
													
											
												
												- django 웹 페이지
 - 2961 도영이가 만든 맛있는 음식
 - 2643 색종이 올려 놓기
 - 18233 java
 - 2661 좋은 수열
 - windows 원격 연결 설정
 - django The requested operation has failed!
 - 공유기 원격 설정
 - 2661 java
 - java di
 - 14711 java
 - 1188 음식 평론가
 - 18233 비트마스킹
 - 2961 java
 - django windows 배포 에러
 - windows apache wsgi 에러
 - 원격 연결 포트 포워딩
 - The requested operation has failed!
 - APPEND_SLASH = FALSE
 - django 프로젝트 시작
 - django settings.py
 - 18233 러버덕
 - django httpd error
 - 1188 java
 - Problems occurred while performing provisioning operation
 - django apache deploy error
 - 14711 타일 뒤집기
 - 2643 java
 - django
 - apache pythonpath
 
													Archives
													
											
									라이브러리는 도서관 아닌가요
크루스칼 알고리즘 (Kruskal Algorithm), MST 최소 신장 트리 본문
< 핵심 >
오름차순으로 정렬된 엣지를 하나씩 뽑아 노드에 연결되는 엣지로 사용할 것인지를 정하는 것이다.
< 구현 방식 >
즉, 두 노드의 루트가 다를 때 작은 값을 가지는 노드를 기준으로 루트를 union한다.
두 노드의 루트가 같다는 것은 하나로 연결이 되어 있다는 뜻이다.
(여기서 한 노드의 루트를 찾는 find 메서드(또는 함수)가 필요해진다.)
만약 두 노드의 루트가 같다면, 연결하지 않는다. → 싸이클(Cycle)이 생성될 수 있다.
예시 코드 (백준 BOJ 1922 네트워크 연결)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
class edge implements Comparable<edge> {
    int a, b;
    int cost;
    edge(int a, int b, int cost){
        this.a = a;
        this.b = b;
        this.cost = cost;
    }
    @Override
    public int compareTo(edge e){
        return this.cost > e.cost ? 1 : -1;
    }
}
public class Main {
    static int[] p; // parent
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int V = Integer.parseInt(br.readLine());
        int E = Integer.parseInt(br.readLine());
        p = new int[V+1];
        for(int i=0; i<=V; ++i){
            p[i] = i;
        }
        StringTokenizer st;
        PriorityQueue<edge> pq = new PriorityQueue<>();
        for(int i=0; i<E; ++i){
            st = new StringTokenizer(br.readLine());
            pq.add(new edge(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())));
        }
        // pq에 넣는 것은 오름차순으로 정렬하기 위한 것이다.
        for(edge e : pq){
            System.out.println(e.cost);
        }
        int ans = 0;
        // edge 수만큼 반복
        for(int i=0; i<E; ++i){
            edge e = pq.poll();
            // 원래 e의 null 검사를 해줘야 한다.
            int aRoot = find(e.a);
            int bRoot = find(e.b);
            // 여기서 이미 비교를 했으므로 union 에서 할 필요가 없다;
            if(aRoot != bRoot){
                union(aRoot, bRoot);
                ans += e.cost;
            }
            // 같으면 무시 --> 싸이클 생성 방지
        }
        System.out.print(ans);
    }
    // 루트 찾아서 반환
    public static int find(int a){
        if(a != p[a]){
            p[a] = find(p[a]);
            return p[a];
        }
        return a;
    }
    // 루트 일치화
    public static void union(int aRoot, int bRoot){
        // + 이미 루트를 구했으므로 구할 필요가 없다.
        // + 이미 main 반복문에서 비교했으므로 할 필요가 없다.
        // a가 더 작은 수니까 a를 넣는 게 맞다.
        p[bRoot] = aRoot;
    }
}
< 활용 >
모든 노드를 최소의 비용으로 연결시키는 설계에 유용하다.
( 각 노드는 한 번씩만 연결되며 싸이클은 존재하지 않는다. )
< 참고 >
실제로 그래프가 만들어진 것은 아니지만,
union을 할 때 노드를 연결하는 로직을 주입하면 연결 정보를 사용할 수 있게 된다.
'자료구조, 알고리즘' 카테고리의 다른 글
| 이분 탐색 ( Binary Search ) (0) | 2022.03.23 | 
|---|---|
| Knapsack Algorithm 배낭 문제 정리 (0) | 2021.10.30 | 
| 우선순위 큐와 힙의 차이 (0) | 2021.10.21 | 
			  Comments