[Algorithm] ๐ŸŒด๋ฐฑ์ค€ 1197 ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ

HaJingJingยท2021๋…„ 5์›” 22์ผ
0

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
48/119

0. ๋ฌธ์ œ

๊ทธ๋ž˜ํ”„๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ๊ทธ ๊ทธ๋ž˜ํ”„์˜ ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ๋Š”, ์ฃผ์–ด์ง„ ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ์ •์ ๋“ค์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋ถ€๋ถ„ ๊ทธ๋ž˜ํ”„ ์ค‘์—์„œ ๊ทธ ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์ด ์ตœ์†Œ์ธ ํŠธ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค.

์ž…๋ ฅ
์ฒซ์งธ ์ค„์— ์ •์ ์˜ ๊ฐœ์ˆ˜ V(1 โ‰ค V โ‰ค 10,000)์™€ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜ E(1 โ‰ค E โ‰ค 100,000)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๋‹ค์Œ E๊ฐœ์˜ ์ค„์—๋Š” ๊ฐ ๊ฐ„์„ ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์„ธ ์ •์ˆ˜ A, B, C๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์ด๋Š” A๋ฒˆ ์ •์ ๊ณผ B๋ฒˆ ์ •์ ์ด ๊ฐ€์ค‘์น˜ C์ธ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. C๋Š” ์Œ์ˆ˜์ผ ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ์ ˆ๋Œ“๊ฐ’์ด 1,000,000์„ ๋„˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ž˜ํ”„์˜ ์ •์ ์€ 1๋ฒˆ๋ถ€ํ„ฐ V๋ฒˆ๊นŒ์ง€ ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ ธ ์žˆ๊ณ , ์ž„์˜์˜ ๋‘ ์ •์  ์‚ฌ์ด์— ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋‹ค. ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ -2,147,483,648๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , 2,147,483,647๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋งŒ ์ž…๋ ฅ์œผ๋กœ ์ฃผ์–ด์ง„๋‹ค.

์ถœ๋ ฅ
์ฒซ์งธ ์ค„์— ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

1. ์•„์ด๋””์–ด

Kruskal Algorithm ์ด์šฉ
๐Ÿ’ก PriorityQueue ์ด์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ€์ค‘์น˜๋ถ€ํ„ฐ ์—ฐ๊ฒฐํ•จ
๐Ÿ’ก ์‚ฌ์ดํด์„ ์ƒ๊ธฐ์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๊ณ , Union & Find ์ด์šฉํ•˜์—ฌ Disjoint set ๊ตฌํ˜„

2. ํ•ต์‹ฌ ํ’€์ด

1) PriorityQueue ์ด์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ€์ค‘์น˜๋ถ€ํ„ฐ ์—ฐ๊ฒฐํ•จ

pq.offer(new Edge(start,end,cost));
...
while(!pq.isEmpty()) {
	Edge e = pq.poll();
			
	if(find(e.start) == find(e.end)) 
    	continue;
	else {
		union(e.start, e.end);
		count+=e.cost;
	}
}

2) findํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์„œ๋กœ์˜ root๊ฐ€ ๊ฐ™์€์ง€ ํ™•์ธ(์‚ฌ์ดํด ์—†์• ๊ธฐ ์œ„ํ•ด)

static int find(int e) {
	if(parent[e] == e) return e;
	return parent[e] = find(parent[e]);
}

3) unionํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์„œ๋กœ๋ฅผ ํŠธ๋ฆฌ๋กœ ์—ฐ๊ฒฐํ•จ

static void union(int a, int b) {
	int rootA = find(a);
	int rootB = find(b);
		
	if(rootA != rootB) 
    	parent[rootB] = rootA;
}

3. ์ฝ”๋“œ

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
public class MST_1 {
	static int[] parent;
	static PriorityQueue<Edge> pq;
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s[] = br.readLine().split(" ");
		
		int count = 0;
		int V = Integer.parseInt(s[0]);
		int E = Integer.parseInt(s[1]);
		parent = new int[V+1];
		pq = new PriorityQueue<Edge>();
		
		for(int i=0; i<V+1; i++)
			parent[i] = i;
		
		for(int i=0; i<E; i++) {
			s = br.readLine().split(" ");
			int start = Integer.parseInt(s[0]);
			int end = Integer.parseInt(s[1]);
			int cost = Integer.parseInt(s[2]);
			pq.offer(new Edge(start,end,cost));
		}
		
		while(!pq.isEmpty()) {
			Edge e = pq.poll();
			
			if(find(e.start) == find(e.end)) continue;
			else {
				union(e.start, e.end);
				count+=e.cost;
			}
		}
		
		System.out.println(count);
	}
	
	static int find(int e) {
		if(parent[e] == e) return e;
		return parent[e] = find(parent[e]);
	}
	
	static void union(int a, int b) {
		int rootA = find(a);
		int rootB = find(b);
		
		if(rootA != rootB) parent[rootB] = rootA;
	}

	static class Edge implements Comparable<Edge>{
		int start;
		int end;
		int cost;
		
		Edge(int start, int end, int cost){
			this.start = start;
			this.end = end;
			this.cost = cost;
		}
		
		@Override
		public int compareTo(Edge o) {
			return this.cost - o.cost;
		}
	}
}

4. ๊ฒฐ๊ณผ

์„ฑ๊ณตโœจ

profile
๐ŸŒฑ์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๐ŸŒฑ

0๊ฐœ์˜ ๋Œ“๊ธ€