[BOJ] 1197.최소스패닝트리
Kruskal Algorithm
-
메모리 : 50,356 KB
-
실행시간 : 504 ms
-
코드길이 : 1,741 B
-
소요시간 : 1H
package baekjoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
public class Main_B_1197_최소스패닝트리_Kruskal {
static int[] parents;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
int V = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());
int[][] edges = new int[E][3];
parents = new int[V + 1];
for (int i = 0; i < E; i++) {
st = new StringTokenizer(in.readLine(), " ");
edges[i][0] = Integer.parseInt(st.nextToken()); // 정점1
edges[i][1] = Integer.parseInt(st.nextToken()); // 정점2
edges[i][2] = Integer.parseInt(st.nextToken()); // 가중치
}
// 가중치를 오름차순으로 정렬
Arrays.sort(edges, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return Integer.compare(o1[2], o2[2]);
}
});
// unionFind를 할 준비 - makeSet과정
for (int i = 1; i < V + 1; i++) {
parents[i] = i;
}
// V-1번 반복하면서 union진행
int cnt = 0;
long result = 0;
for (int i = 0; i < E; i++) {
int a = findSet(edges[i][0]);
int b = findSet(edges[i][1]);
if (a == b)
continue;
union(a, b);
result += edges[i][2];
cnt++;
if (cnt == V - 1)
break;
}
System.out.println(result);
in.close();
}
static int findSet(int x) {
if (parents[x] == x)
return x;
return parents[x] = findSet(parents[x]);
}
static void union(int a, int b) {
int px = findSet(a);
int py = findSet(b);
parents[py] = px;
}
}
Prim Algorithm
-
메모리 : 57,220 KB
-
실행시간 : 692 ms
-
코드길이 : 1,888 B
package baekjoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main_B_1197_최소스패닝트리_Prim {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
int V = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());
long result = 0;
ArrayList<Edge>[] adj = new ArrayList[V];
for (int i = 0; i < V; i++) {
adj[i] = new ArrayList<>();
}
for (int i = 0; i < E; i++) {
st = new StringTokenizer(in.readLine(), " ");
int a = Integer.parseInt(st.nextToken()); // 정점1
int b = Integer.parseInt(st.nextToken()); // 정점2
int c = Integer.parseInt(st.nextToken()); // 가중치
adj[a-1].add(new Edge(b - 1, c));
adj[b-1].add(new Edge(a - 1, c));
}
PriorityQueue<Edge> pq = new PriorityQueue<>();
Edge[] dist = new Edge[V];
// dist안의 각 거리들은 무한대
for (int i = 1; i < V; i++) {
dist[i] = new Edge(i, Integer.MAX_VALUE);
pq.add(dist[i]);
}
boolean[] mst = new boolean[V + 1];
// 시작점은 0
dist[0] = new Edge(0, 0);
pq.add(dist[0]);
while (!pq.isEmpty()) {
// 현재 dist가 가장 작은 친구를 데려와서
Edge e = pq.poll();
if (mst[e.dest]) {
continue;
}
mst[e.dest] = true;
result += e.cost;
// 그 친구로부터 출발하는 모든 간선에 대해서
for (Edge next : adj[e.dest]) {
// 그 간선의 목적지가 아직 pq에 들어있는 정점이라면
// 그리고 더 빨리 도착할 수 있다면
if (!mst[next.dest] && dist[next.dest].cost > next.cost) {
// dist갱신
dist[next.dest].cost = next.cost;
// decrease key연산
pq.remove(dist[next.dest]);
pq.add(dist[next.dest]);
}
}
}
System.out.println(result);
in.close();
}
static class Edge implements Comparable<Edge> {
int dest;
int cost;
Edge(int d, int c) {
dest = d;
cost = c;
}
@Override
public int compareTo(Edge o) {
return Integer.compare(this.cost, o.cost);
}
}
}
Leave a comment