반응형

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

 

1197번: 최소 스패닝 트리

첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이

www.acmicpc.net

package com.ji.beakjoon.tree;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

/**
 * 최소 신장 트리
 * Kruskal Algo
 * 1. 가중치가 가장 작은 간선을 찾아서 선택
 * 2. 가중치가 작은 간선이 값이 동일할 경우 노드의 번호가 빠른거 선택
 * 3. 순환이 생길 경우는 건너뜀
 * @author ji
 *
 */
public class MST {

	static int n, m;
	static int[] parent;
	static PriorityQueue<edge> pq = new PriorityQueue<edge>();
	static int result = 0;

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(br.readLine());

		n = Integer.parseInt(st.nextToken());//정점 갯수
		m = Integer.parseInt(st.nextToken());//간선 갯수

		parent = new int[n + 1];

		for (int i = 0; i < n + 1; i++) {
			parent[i] = i;
		}

		for (int i = 0; i < m; i++) {
			st = new StringTokenizer(br.readLine());
			//A정점, B정점, 간선 가중치
			pq.add(new edge(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken())));
		}

		// 시작점과 종료점의 최상위 노드를 찾아서 겹치면 사이클이 생기는 것이므로 continue를 한다.
		// 아니면 union을 통해 연결하고 v(가중치) 를 더해준다.
		for (int i = 0; i < m; i++) {
			edge tmp = pq.poll();

			int a = find(tmp.s);
			int b = find(tmp.e);

			//순환이 생기므로 패스
			if (a == b)
				continue;
			union(a, b);
			result += tmp.v;
		}

		System.out.println(result);

	}

	// 이 부분이 이해가 확실히 가지 않음 !!!
	// 크루스칼의 기본 union find!! 외워두는게 편하다.
	public static int find(int a) {
		if (a == parent[a])
			return a;
		parent[a] = find(parent[a]);
		return parent[a];
	}

	public static void union(int a, int b) {
		int aRoot = find(a);
		int bRoot = find(b);

		if (aRoot != bRoot) {
			parent[aRoot] = b;
		} else {
			return;
		}
	}
}

//간선 class
//우선순위 큐를 사용하기 위해서 Comparable을 통해 정렬 우선순위를 정했다. (V 기준)
//가중치가 작은 간선을 선택!!!
class edge implements Comparable<edge> {
	int s;
	int e;
	int v;

	public edge(int s, int e, int v) {
		this.s = s;
		this.e = e;
		this.v = v;
	}

	@Override
	public int compareTo(edge arg0) {
		// TODO Auto-generated method stub
		return arg0.v >= this.v ? -1 : 1;
	}

}
728x90

'[개발관련] > 코테준비' 카테고리의 다른 글

[프로그래머스] 네트워크  (0) 2021.08.07
[프로그래머스] 체육북  (0) 2021.08.07
[백준] 소문난 칠공주  (0) 2021.08.07
[백준] 일곱 난쟁이  (0) 2021.08.07
[백준] 토너먼트  (0) 2021.08.07

+ Recent posts