[JAVA/백준] 1922번: 네트워크 연결

👀 문제

https://www.acmicpc.net/problem/1922

👊 도전

1. 설계

  1. MST 문제이다.
  2. 이를 해결하기 위해, 크루스칼 알고리즘을 쓴다.
  3. 우선순위 큐를 이용해 최소비용 먼저 체크한다.
  4. a, b의 최상위 부모를 찾고, 같다면 이미 연결된 컴퓨터이므로 패스한다.
  5. 아닐 경우 둘을 연결한다.

2. 구현 (성공 코드)

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
import java.util.*;
import java.io.*;
/**
 * @author HEESOO
 *
 */
/*
 * MST?
 * int[] parent, 초기화
 * Node 클래스 생성하고, 우선순위 큐에 다 넣어
 * 부모가 같으면 패스, 다르면 union하고 sum+=weight*/

class Main {
	static PriorityQueue<Node> pq;
	static int[] parent;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		int n=Integer.parseInt(br.readLine());
		int m=Integer.parseInt(br.readLine());
		pq=new PriorityQueue<>();
		parent=new int[n+1];
		for(int i=1;i<=n;i++) parent[i]=i; // 부모는 자기 자신
		
		for(int i=0;i<m;i++) {
			st=new StringTokenizer(br.readLine());
			int a=Integer.parseInt(st.nextToken());
			int b=Integer.parseInt(st.nextToken());
			int c=Integer.parseInt(st.nextToken());
			pq.offer(new Node(a, b, c));
		}
		
		System.out.println(solve());
	}
	
	public static int solve() {
		int sum=0;
		
		while(!pq.isEmpty()) { // 가중치 작은 것 먼저 뽑음
			Node node=pq.poll();
			int parentS=find(node.start);
			int parentE=find(node.end);
			if(parentS==parentE) continue; // 둘이 연결되어 있는 경우이므로 패스
			union(parentS, parentE); // 둘을 연결 짓기
			sum+=node.weight; // 최소비용 추가
		}
		
		return sum;
	}
	
	public static int find(int x) { // x의 최상위 부모 리턴
		if(x==parent[x]) return x;
		else return parent[x]=find(parent[x]);
	}
	
	public static void union(int a, int b) { // a, b를 연결
		parent[a]=b;
	}

}

class Node implements Comparable<Node>{
	int start;
	int end;
	int weight;
	
	public Node(int s, int e, int w) {
		this.start=s;
		this.end=e;
		this.weight=w;
	}
	
	@Override
	public int compareTo(Node n) {
		return this.weight-n.weight;
	}
}

3. 결과

실행결과 🤟 성공 🤟

4. 설명

  1. 크루스칼 알고리즘을 이용한다
    • MST는 크루스칼 또는 프림으로 해결할 수 있다.
    • 크루스칼을 쓸 때는 둘의 최상위 부모를 체크하고, 같다면 이미 연결되어있는 것이므로 패스, 아니면 둘을 합친다. 이를 위해 Union-Find를 쓴다.
    • MST는 결국 최소 가중치를 가지는 그래프를 만드는 것이기 때문에, 노드 탐색을 가중치가 작은 것들 먼저 확인해야 한다. 따라서 우선순위 큐를 이용한다.

👏 해결 완료!

참고