๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜/๋ฌธ์ œ

[์ž๋ฐ”] ๋ฐฑ์ค€ 1197 - ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ

by applemango2021 2021. 1. 5.

์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ(MST) ๋ฌธ์ œ๋Š” ๋ณดํ†ต ํฌ๋ฃจ์Šค์นผ์ด๋‚˜ ํ”„๋ฆผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. 

 

- ํฌ๋ฃจ์Šค์นผ : ๊ฐ„์„  ์œ„์ฃผ๋กœ ์ƒ๊ฐ. ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฐ„์„ ์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ฐ„์„ ์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค.

     · ์‹œ๊ฐ„๋ณต์žก๋„๋Š” ๊ฐ„์„ ์ด e๊ฐœ ์žˆ์„ ๋•Œ  O(elogโ‚‚e)  

- ํ”„๋ฆผ : ๋…ธ๋“œ ์œ„์ฃผ๋กœ ์ƒ๊ฐ. ๋…ธ๋“œ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜์—ฌ ๊ทธ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๊ฐ„์„  ์ค‘ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์„ ์„ ํƒํ•ด๊ฐ€๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค.

     · ์‹œ๊ฐ„๋ณต์žก๋„๋Š” ๋…ธ๋“œ๊ฐ€ n๊ฐœ ์žˆ์„ ๋•Œ  O(n^2)

  

๋‘˜ ๋‹ค ๊ณตํ†ต์ ์ธ ๊ฑด, ์‚ฌ์ดํด์ด ์ƒ๊ธฐ๋ฉด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ๋‹ˆ์˜จ-ํŒŒ์ธ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ.

 


์ด ๋ฌธ์ œ๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ๋‚ฎ์€ ๊ฐ„์„ ์„ ์„ ํƒํ•ด๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ํ’€์—ˆ๋‹ค. 

๋ฐฉ๋ฒ• 1. ๊ฐ ๊ฐ„์„ ๋“ค์„ ArrayList์— ๋‹ด์•„์„œ Collections.sort๋ฅผ ํ•œ ๋‹ค์Œ์— for-each๋ฅผ ํ†ตํ•ด ๊ฐ„์„  ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ• 2. ๊ฐ ๊ฐ„์„ ๋“ค์„ PriorityQueue์— ๋‹ด์•„์„œ while๋ฌธ์œผ๋กœ ๋ชจ๋“  ๊ฐ„์„ ๋“ค์„ ์ฒดํฌํ•˜๋Š” ๋ฐฉ๋ฒ• 

 

์ž‘๋…„์—๋Š” ๋ฐฉ๋ฒ• 1๋กœ ํ’€์—ˆ๊ณ , ์ด๋ฒˆ์—๋Š” ๋ฐฉ๋ฒ• 2๋กœ ํ’€์—ˆ๋Š”๋ฐ ๋ฏธ์„ธํ•˜๊ฒŒ ๋ฐฉ๋ฒ• 1์ด ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค.

/* 2021.01.05(ํ™”) */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;

public class Main {
	
	static int[] parent;
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] str = br.readLine().trim().split(" ");
		int V = Integer.parseInt(str[0]);
		int E = Integer.parseInt(str[1]);
		int total = 0;
		
		parent = new int[V+1];
		for(int i=0;i<=V;i++) parent[i] = i;
		
		
		int start = 0, end = 0, weight = 0;
		PriorityQueue<Edge> pq = new PriorityQueue<Edge>();
		for(int i=0;i<E;i++) {
			str = br.readLine().trim().split(" ");
			
			start 	= Integer.parseInt(str[0]);
			end 	= Integer.parseInt(str[1]);
			weight 	= Integer.parseInt(str[2]);
			
			pq.offer(new Edge(start, end, weight));
		}
		
		Edge currEdge;
		while(!pq.isEmpty()) {
			currEdge = pq.poll();
			
			//์‹œ์ž‘ ๋…ธ๋“œ์™€ ๋ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ๊ฐ€ ๊ฐ™๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ„์„ ์„ ์„ ํƒํ•ด์„œ ๊ฒฝ๋กœ๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ, 
			//์‚ฌ์ดํด์ด ์ƒ์„ฑ๋˜์–ด ๋ฒ„๋ฆฐ๋‹ค. 
			//--> ๋ถ€๋ชจ๊ฐ€ ๊ฐ™๋‹ค๋ฉด ๊ฐ„์„ ์„ ์„ ํƒํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๋„˜์–ด๊ฐ„๋‹ค.
			if(hasSameParent(currEdge.s, currEdge.e)) continue;
			
			//์‚ฌ์ดํด์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ํ•ด๋‹น ๊ฐ„์„ ์„ ์„ ํƒํ•œ๋‹ค.
			//--> s์™€ e์˜ ๋ถ€๋ชจ๋ฅผ ํ•ฉ์ณ์ฃผ๊ณ , ๊ฐ€์ค‘์น˜๋ฅผ total ๋ณ€์ˆ˜์— ๋”ํ•ด์ค€๋‹ค. 
			union(currEdge.s, currEdge.e);
			total += currEdge.w;
		}
		
		System.out.println(total);
	}
	
	private static void union(int x, int y) {
		x = find(x);
		y = find(y);
		
		//์ž‘์€ ์ˆซ์ž์˜ parent๋กœ ํ†ต์ผ์‹œ์ผœ์ฃผ๊ธฐ๋กœ ํ–ˆ์œผ๋‹ˆ๊นŒ,
		//์ตœ์ข…์ ์œผ๋กœ ๋…ธ๋“œ๋“ค์€ parent๊ฐ€ ์ „๋ถ€ 1์ผ ๊ฒƒ
		//(1๋ถ€ํ„ฐ V๊นŒ์ง€ ๋ชจ๋‘ ์—ฐ๊ฒฐ์‹œ์ผœ์•ผ ํ•˜๋‹ˆ๊นŒ!)
		if(x>y) parent[x] = y;
		else parent[y] = x;
	}

	private static boolean hasSameParent(int s, int e) {
		int sParent = find(s);
		int eParent = find(e);
		
		if(sParent==eParent) return true;
		else return false;
	}

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

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