PS/inflearn java coding2022. 4. 14. 21:29

* 크루스칼

 

최소 스패닝 트리의 특성,

1. 회로가 없다. (연결되면 그래프가 된다)

- 회로의 구성여부는 Union & Find로 판단한다.

2. Vertex의 수 -1 == Edge의 수

- 시간복잡도 줄일 경우 사용.

 

 

 

전략,

입력된 정점 정보를 cost기준으로 오름차순 정렬 이후, Union이 아닌 경우 선택한다. 

(cost가 작은 녀석부터 Union이 된다 => 최소 비용)

 

 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

//원더랜드
//간선을 오름차순 정렬
class Main {

	static int m, n, answer;

	static int[] unf;
	public static int Find(int v) {
		if (v == unf[v]) return v;
		else return unf[v]=Find(unf[v]);
	}
	
	public static void Union ( int a , int b) {
		int fa = Find(a);
		int fb = Find(b);
		if( fa != fb)  unf[fa]=fb;		
	}
	public static void main(String args[]) throws Exception {
		Main M = new Main();
		Scanner in = new Scanner(System.in);
		//도시 개수
		n = in.nextInt();
		//간선개수
		m = in.nextInt();
		ArrayList<Edge> arr = new ArrayList<>();
		unf = new int [n+1];
		
		//유니온 초기화 (자기 자신의 값)
		for (int i = 1 ; i <= n ; i++ ) unf[i] = i;
		for (int i =0 ;  i < m; i++) {
				int a = in.nextInt();
				int b = in.nextInt();
				int c = in.nextInt();
				arr.add( M.new Edge(a, b, c));
		}
		
		//cost에 대해 오름차순 정렬
		Collections.sort(arr);
		
		//회로가 아닌 것만 누적하며 선택
		for ( Edge ob : arr) {
			int fv1 = Find(ob.v1);
			int fv2 = Find(ob.v2);
			

			//서로소 관계일 경우 누적
			if (fv1 != fv2) {
				answer += ob.cost;
				Union(fv1, fv2);
			}
			
		}
		
		System.out.println(answer);
		

	}
	class Edge implements Comparable<Edge>{
		
		int v1;
		int v2;
		int cost;
		Edge( int v1, int v2, int cost){
			this.v1 = v1;
			this.v2 = v2;
			this.cost = cost;
			
		}
		@Override
		public int compareTo(Main.Edge o) {
			return this.cost - o.cost;
		}		
	}
}
ex)
input
9 12
1 2 12
1 9 25
2 3 10
2 8 17
2 9 8
3 4 18
3 7 55
4 5 44
5 6 60
5 7 38
7 8 35
8 9 15
output
196

 

 

 

* Prim 

 

우선순위 큐 사용.

1. 0번 정점에서 출발하는 것으로 가정 => pQ.offer( new Edge(1,0) );

2. 방문하는 vex의 ch리스트를 통해 회로를 차단.

3. 인접 리스트에서 현재 vex의 간선을 pQ에 모두 넣어준다. 

4. pQ에서 가장 cost가 작은 간선을 선택한다 (Greedy 기법) 

5. 결국 cost가 큰 간선들은 모두 버려진다.

 


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

//원더랜드
class Main {

	static int m, n, answer;


	public static void main(String args[]) throws Exception {
		Main M = new Main();
		Scanner in = new Scanner(System.in);
		//도시 개수
		n = in.nextInt();
		//간선개수
		m = in.nextInt();
		
		ArrayList<ArrayList<Edge>> graph = new ArrayList<ArrayList<Edge>>();
		
		for ( int i = 0 ; i <=n; i++) {
			graph.add( new ArrayList<Edge>());
		}
		
		//방문 체크를 위한 배열
		int [] ch = new int[n+1];
		for (int i= 0; i < m ; ++i ) {
			int a = in.nextInt();
			int b = in.nextInt();
			int c = in.nextInt();
			
			//무방향성 그래프의 인접리스트 생성
			graph.get(a).add(M.new Edge(b, c));
			graph.get(b).add(M.new Edge(a, c));
		}

		PriorityQueue<Edge> pQ = new PriorityQueue<>();
		
		//초기 값을 0번 노드에서 cost 0으로 간주
		pQ.offer(M.new Edge(1, 0));
		
		while(!pQ.isEmpty()) {
			Edge tmp = pQ.poll();
			
			//end vertex
			int ev = tmp.vex;
			if( ch[ev] == 0 ) {
				ch[ev] = 1;
				//비용 누적
				answer += tmp.cost;
				//ev의 인접 리스트를 탐색하여 방문하지 않은 정점을 offer
				for (Edge ob : graph.get(ev)) {
					//이미 선택된 정점은 계산하지 않음.
					if(ch[ob.vex] == 0)  
						pQ.offer(M.new Edge(ob.vex, ob.cost));					
				}
			}
		}
		

		System.out.println(answer);
		

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

ex)
input
9 12
1 2 12
1 9 25
2 3 10
2 8 17
2 9 8
3 4 18
3 7 55
4 5 44
5 6 60
5 7 38
7 8 35
8 9 15
output
196

'PS > inflearn java coding' 카테고리의 다른 글

최대길이증가수열  (0) 2022.04.14
계단오르기  (0) 2022.04.14
Union & Find  (0) 2022.04.14
최대 수입  (0) 2022.04.14
결혼식 (Greedy)  (0) 2022.04.14
Posted by easy16