BOJ 1647: 도시 분할 계획 https://www.acmicpc.net/problem/1647
최소 스패닝 트리
를 구한다.long타입
으로 선언해 구한다.크루스칼 알고리즘
을 사용한다.Union&Find
를 사용해 트리에 사이클이 있는지 확인한다.package project1;
import java.util.*;
import java.io.*;
public class Main {
static int N, M;
static int[] parent; // 집합 기록할 배열
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
long answer = 0;
st = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
Edge[] edges = new Edge[M];
for(int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine(), " ");
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
// 더 작은 마을 번호가 앞으로 가게 저장
if(a <= b) {
edges[i] = new Edge(a, b, c);
} else {
edges[i] = new Edge(b, a, c);
}
}
// 유지비를 기준으로 오름차순 정렬
Arrays.sort(edges, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Integer.compare(o1.cost, o2.cost);
}
});
// 집합 저장할 배열 초기화
parent = new int[N + 1];
for(int i = 1; i <= N; i++) {
parent[i] = i;
}
int target = 0; // 연결한 길 중 가장 큰 값 구하기 -> 나중에 이 길을 제거하면 마을이 2개로 갈라짐
// 크루스칼 시작
for(int i = 0; i < M; i++) {
Edge edge = edges[i];
// 사이클이 없다면
if(!isSameParent(edge.s, edge.e)) {
// 합치기
union(edge.s, edge.e);
// 유지비 누적
target = Math.max(target, edge.cost); // 연결한 길 중 가장 큰 값 구하기
answer += edge.cost;
}
}
// 연결된 모든 길 중 유지비가 가장 큰 길은 제거 -> 마을 2개로 갈라지는 효과
System.out.println(answer - target);
}
// 하나의 집합으로 합치기
static void union(int x, int y) {
x = find(x);
y = find(y);
// 마을 번호가 더 작은 집합으로 합침
if(x < y) {
parent[y] = x;
} else {
parent[x] = y;
}
}
// 어느 집합에 속해있는지 확인
static int find(int x) {
if(parent[x] == x) {
return x;
}
return parent[x] = find(parent[x]);
}
// 같은 집합에 속해 있는지 확인 -> 사이클인지 확인함
static boolean isSameParent(int x, int y) {
x = find(x);
y = find(y);
if(x == y) {
return true;
}
return false;
}
static class Edge {
int s, e, cost;
public Edge(int s, int e, int cost) {
this.s = s;
this.e = e;
this.cost = cost;
}
}
}