첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다.
다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다.
이는 A번 정점과 B번 정점이 가중치 C인 간선으로 연결되어 있다는 의미이다.
C는 음수일 수도 있으며, 절댓값이 1,000,000을 넘지 않는다.
그래프의 정점은 1번부터 V번까지 번호가 매겨져 있고, 임의의 두 정점 사이에 경로가 있다.
최소 스패닝 트리의 가중치가 -2,147,483,648보다 크거나 같고, 2,147,483,647보다 작거나 같은 데이터만 입력으로 주어진다.
첫째 줄에 최소 스패닝 트리의 가중치를 출력한다.
최소 신장 트리를 구하는 크루스칼 알고리즘 문제!
처음 알게 된 개념에 대해서 정리하고 넘어갈 수 있는 문제
간선의 가중치에 따라서 오름차순으로 정렬한 뒤,
정점들을 점차 연결해나간다.
이때 같은 루트 노드를 갖는 정점들끼리를 사이클을 생성하기 때문에,
같은 집합으로 합칠 수 없다.
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.StringTokenizer;
class Edge {
int s, e, cost;
Edge(int s, int e, int cost) {
this.s = s;
this.e = e;
this.cost = cost;
}
}
public class Code1197 {
static int V, E;
static int[] parents;
static ArrayList<Edge> edges;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
V = Integer.parseInt(st.nextToken());
E = Integer.parseInt(st.nextToken());
edges = new ArrayList<>();
int answer = 0;
for (int i = 0; i < E; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
edges.add(new Edge(start, end, cost));
}
edges.sort(new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Integer.compare(o1.cost, o2.cost);
}
});
parents = new int[V + 1];
for (int i = 1; i <= V; i++) {
parents[i] = i;
}
for (int i = 0; i < E; i++) {
Edge edge = edges.get(i);
if (!sameParent(edge.s, edge.e)) {
union(edge.s, edge.e);
answer += edge.cost;
}
}
System.out.println(answer);
}
public static int find(int x) {
if (parents[x] == x) return x;
else return parents[x] = find(parents[x]);
}
public static boolean sameParent(int x, int y) {
return find(x) == find(y);
}
public static void union(int x, int y) {
x = find(x);
y = find(y);
if (x != y) {
parents[y] = x;
}
}
}