SWEA3124 최소 스패닝 트리

·2022년 4월 27일
0

SWEA 알고리즘

목록 보기
27/29


크루스칼 알고리즘을 사용해 구할 수 있다.
크루스칼 알고리즘이란 가중치가 가장 작은 간선부터 하나씩 연결해나가는 방식이다.

이 문제에서는 정점의 수가 매우 많기 때문에 인접행렬을 사용할 수 없고, Union-Find 알고리즘을 이용해 풀 수 있다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Solution {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	static StringTokenizer st;
	static int N;
	static int[] parents;
	static Edge[] edgeList;

	static class Edge implements Comparable<Edge> {
		int from, to, weight;

		public Edge(int from, int to, int weight) {
			super();
			this.from = from;
			this.to = to;
			this.weight = weight;
		}

		@Override
		public int compareTo(Edge o) {
			return this.weight - o.weight;
		}

	}

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

		int T = Integer.parseInt(br.readLine());
		for (int tc = 1; tc <= T; tc++) {
			st = new StringTokenizer(br.readLine(), " ");
			N = Integer.parseInt(st.nextToken());
			int E = Integer.parseInt(st.nextToken());
			edgeList = new Edge[E];

			for (int i = 0; i < E; i++) {
				st = new StringTokenizer(br.readLine(), " ");
				int from = Integer.parseInt(st.nextToken()) - 1;
				int to = Integer.parseInt(st.nextToken()) - 1;
				int weight = Integer.parseInt(st.nextToken());
				edgeList[i] = new Edge(from, to, weight);
			}

			Arrays.sort(edgeList); // 간선 비용의 오름차순 정렬
			makeSet();

			int cnt = 0;
			long result = 0;
			for (Edge edge : edgeList) {
				if (union(edge.from, edge.to)) {
					result += (long)edge.weight;
					if (++cnt == N - 1)
						break;
				}
			}

			bw.append("#" + tc + " " + result + "\n");

		}
		bw.flush();
	}

	static void makeSet() {
		parents = new int[N];
		for (int i = 0; i < N; i++) {
			parents[i] = i;
		}
	}

	static int findSet(int a) {
		if (parents[a] == a)
			return a;
		return parents[a] = findSet(parents[a]);
	}

	static boolean union(int a, int b) {
		int aRoot = findSet(a);
		int bRoot = findSet(b);
		if (aRoot == bRoot)
			return false;

		parents[bRoot] = aRoot;
		return true;
	}
}
profile
SSAFY 7기

0개의 댓글