https://www.acmicpc.net/problem/27498
크루스칼 알고리즘을 응용하여 간단히 풀이할 수 있는 문제였다.
로직은 다음 과정을 거쳐 전개된다.
로직의 시간복잡도는 크루스칼을 사용하는 부분의 으로 수렴하고 이는
인 최악의 경우에도 무난히 제한 조건 1초를 통과한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import static java.lang.Integer.parseInt;
public class Main {
static int[] parent;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = parseInt(st.nextToken());
int M = parseInt(st.nextToken());
parent = new int[N + 1];
Arrays.fill(parent, -1);
int count = 0;
PriorityQueue<Edge> pq = new PriorityQueue<>((e1, e2) -> Integer.compare(e2.w, e1.w));
while (M-- > 0) {
st = new StringTokenizer(br.readLine());
int u = parseInt(st.nextToken());
int v = parseInt(st.nextToken());
int w = parseInt(st.nextToken());
boolean success = parseInt(st.nextToken()) == 1;
if (success) {
union(u, v);
count++;
continue;
}
pq.add(new Edge(u, v, w));
}
int sum = 0;
while (count < N - 1) {
Edge e = pq.poll();
if (!union(e.u, e.v)) {
sum += e.w;
continue;
}
count++;
}
sum += pq.stream().mapToInt(e -> e.w).sum();
System.out.println(sum);
br.close();
}
static int find(int u) {
if (parent[u] < 0) return u;
return parent[u] = find(parent[u]);
}
static boolean union(int u, int v) {
int p1 = find(u);
int p2 = find(v);
if (p1 == p2) return false;
if (parent[p1] < parent[p2]) {
parent[p2] += parent[p1];
parent[p1] = p2;
} else {
parent[p1] += parent[p2];
parent[p2] = p1;
}
return true;
}
static class Edge {
int u, v, w;
public Edge(int u, int v, int w) {
this.u = u;
this.v = v;
this.w = w;
}
}
}