문제 풀이(8)

Youngseon Kim·2023년 8월 14일
0

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

import java.io.*;
import java.util.*;



class Node{
	double x;
	double y;
	int index;

	Node(double x , double y, int index)
	{
		this.x = x;
		this.y = y;
		this.index = index;
	}

	@Override
	public String toString()
	{
		return x +" "+ y+" "+index;
	}
}


class Edge implements Comparable  <Edge>{

	int s;
	int e;
	double v;

	Edge(int s , int e , double v)
	{
		this.s = s;
		this.e = e;
		this.v = v;
	}

	@Override
	public int compareTo(Edge oterNode)
	{
		return (int)this.v - (int)oterNode.v;
	}

}

public class Main {

	static PriorityQueue<Edge> pq = new PriorityQueue<>();

	static int[] parent;

	public static void main(String[] args) throws IOException {
		
		BufferedReader br = 
        new BufferedReader(new InputStreamReader(System.in));

		int n = Integer.parseInt(br.readLine());

		Node[] nodes = new Node[n];

		

		for (int i = 0; i < n; i++) {
			
			StringTokenizer st = new StringTokenizer(br.readLine());

			double x = Double.parseDouble(st.nextToken());

			double y = Double.parseDouble(st.nextToken());
			
			nodes[i] = new Node(x, y,i);
		}
		

		for (int i = 0; i < n; i++) {
			for (int j = i+1; j < n; j++) {
			
			
				Node n1 = nodes[i];

				Node n2 = nodes[j];

				
				double result = distance(n1 , n2 );

				pq.offer(new Edge(i, j, result));


			}

			
		}


		parent = new int[n];

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

		int useEdge = 0;

		double result = 0;

		while (useEdge < n - 1) {
			Edge now = pq.poll();

			if (find(now.s) != find(now.e)) {
				union(now.s , now.e);

				result = result + now.v;
			
				useEdge++;
			}
		}

		System.out.printf("%.2f",result);
	}

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

		if (a != b) {
			parent[b] = a;
		}
	}

	public static int find(int a)
	{
		if (a == parent[a]) {
			return a;
		}else{
			return parent[a] = find(parent[a]);
		}
	}


	public static double distance( Node n1 , Node n2)
	{

		double dx = n1.x - n2.x ;
		double dy = n1.y - n2.y ;

		return Math.sqrt((dx * dx) + (dy * dy));
	}
}

먼저 점의 개수 n을 입력 받고, n개의 좌표를 입력 받아서 nodes 배열에 저장한다.입력 받은 좌표들 간의 거리를 계산하여 모든 가능한 간선을 우선순위 큐(pq)에 저장한다. 이때 거리가 짧은 간선이 먼저 나오도록 정렬된다.parent 배열을 생성하고, 각 노드의 부모를 자기 자신으로 초기화한다.
크루스칼 알고리즘을 이용하여 최소 신장 트리를 구성한다. 간선의 가중치가 작은 순서대로 간선을 선택하며, Union-Find를 통해 사이클을 만들지 않는 간선만을 선택한다.최소 비용 스패닝 트리의 비용을 소수 둘째 자리까지 출력한다.

0개의 댓글