백준 문제
백준 1647 (도시 분할 계획)
kangyuseok
2024. 3. 19. 19:26
728x90
1647번: 도시 분할 계획
첫째 줄에 집의 개수 N, 길의 개수 M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번
www.acmicpc.net
임의의 두 노드에서 모두 도달할 수 있는 그래프가 주어지고 각 노드 사이에는 비용이 있는 간선이 주어진다.
이 때 그래프를 둘로 나눈다. 나눈 각각의 그래프는 서로 연결되어 있어야 하고 간선의 합이 최소여야 한다.
두 그래프의 각각의 간선의 합이 최솟값을 구해라.
그래프는 최소 1개의 노드가 존재해야 한다.
문제를 잘보면 크루스칼 알고리즘을 사용하는 것을 알 수 있다.
하지만 어떻게 2개로 나눌까??
잘 생각해보면 간단하다.
결국 그래프 간선의 합이 최소인것을 구하면 된다.
따라서 모든 노드를 크루스칼로 연결해주고 마지막 노드랑 연결된 간선만 제거해 주면 된다.
List<Integer>edge = new ArrayList<>(); //간선 정보 넣어주기
for(Info i : list){
int a = i.a;
int b = i.b;
if(find(a) != find(b)) {
union(a, b);
edge.add(i.cost);
}
}
for(int i=0;i<edge.size()-1;i++)ans+=edge.get(i);
System.out.println(ans);
위 코드는 크루스칼 알고리즘을 수행하는 부분이다.
그래프를 연결해주면서 간선의 정보를 edge에 넣어준다.
마지막에 edge에서 for문을 돌면서 edge.size - 1 만큼 누적으로 합해준다.
마지막으로 연결된 간선을 뺴줘야 하기 때문이다.
public class Main{
private 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 = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
parent = new int[n+1];
Set<Integer> set = new HashSet<>();
for(int i=1;i<=n;i++){
parent[i] = i;
set.add(i);
}
List<Info> list = new ArrayList<>();
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());
list.add(new Info(a, b, c));
}
Collections.sort(list);
int ans = 0;
List<Integer>edge = new ArrayList<>();
for(Info i : list){
int a = i.a;
int b = i.b;
if(find(a) != find(b)) {
union(a, b);
edge.add(i.cost);
}
}
for(int i=0;i<edge.size()-1;i++)ans+=edge.get(i);
System.out.println(ans);
}
private static int find(int u){
if(parent[u]== u)return u;
return parent[u] = find(parent[u]);
}
private static void union(int a, int b){
a = find(a);
b = find(b);
if(a== b)return;
parent[a] = b;
}
}
class Info implements Comparable<Info>{
int a;
int b;
int cost;
Info(int a, int b, int cost){
this.a = a;
this.b = b;
this.cost = cost;
}
@Override
public int compareTo(Info i){
return this.cost - i.cost;
}
}