티스토리 뷰
https://www.acmicpc.net/problem/14950
14950번: 정복자
서강 나라는 N개의 도시와 M개의 도로로 이루어졌다. 모든 도시의 쌍에는 그 도시를 연결하는 도로로 구성된 경로가 있다. 각 도로는 양방향 도로이며, 각 도로는 사용하는데 필요한 비용이 존재
www.acmicpc.net

문제
서강 나라는 N개의 도시와 M개의 도로로 이루어졌다. 모든 도시의 쌍에는 그 도시를 연결하는 도로로 구성된 경로가 있다. 각 도로는 양방향 도로이며, 각 도로는 사용하는데 필요한 비용이 존재한다. 각각 도시는 1번부터 N번까지 번호가 붙여져 있다. 그 중에서 1번 도시의 군주 박건은 모든 도시를 정복하고 싶어한다.
처음 점거하고 있는 도시는 1번 도시 뿐이다. 만약 특정 도시 B를 정복하고 싶다면, B와 도로로 연결된 도시들 중에서 적어도 하나를 정복하고 있어야 한다. 조건을 만족하는 도시 중에서 하나인 A를 선택하면, B를 정복하는 과정에서 A와 B를 연결하는 도로의 비용이 소모된다. 박건은 한번에 하나의 도시만 정복을 시도하고 언제나 성공한다. 한 번 도시가 정복되면, 모든 도시는 경계를 하게 되기 때문에 모든 도로의 비용이 t만큼 증가하게 된다. 한 번 정복한 도시는 다시 정복하지 않는다.
이때 박건이 모든 도시를 정복하는데 사용되는 최소 비용을 구하시오.
유형 : MST
접근 방식
- 시간이 매초 t씩 증가하기 때문에 조금 헷갈릴 수 있지만 상관없다.
- 결국 완성된 정복 국가의 형태는 MST이다.
- 즉 매번 점령된 땅을 기준으로 확장하는 (프림 알고리즘)의 결과나 크루스칼의 결과나 똑같다는 것이다.
- 그저 간선을 한 개 고를 때마다 t값의 증가만 잘 고려하면 되는 문제이다.
- 예제를 예로 들어 설명하자면 아래 설명에는
- 2 + (1+8) + (2+8+8)이지만
- 이 방식을 크루스칼로 풀 경우 1 + (2+8) + (2+8+8)인데 차이가 없다는 것이다 !
전체 코드
import java.util.*;
import java.io.*;
public class Main {
static int n = 0;
static int m = 0;
static int t = 0;
static int[] root;
public static void main(String[] args) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine(), " ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
t = Integer.parseInt(st.nextToken());
root = new int[n+1];
for(int i=1;i<=n;i++){
root[i] = i;
}
PriorityQueue<Node> pq = new PriorityQueue<>(
(x,y) -> x.c - y.c
);
for(int i=1;i<=m;i++){
st = new StringTokenizer(bf.readLine(), " ");
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
int v3 = Integer.parseInt(st.nextToken());
pq.add(new Node(v1,v2,v3));
}
int tmp = 0;
int result = 0;
int num = 0;
while(!pq.isEmpty()){
Node cur = pq.poll();
if(find(cur.v1) != find(cur.v2)){
union(cur.v1,cur.v2);
result += tmp + cur.c;
tmp += t; // 간선을 한 개 뽑을 때 마다 t초씩 값 증가 (0 -> 8 -> 8+8)
num += 1; // n-1개의 간선을 뽑을 경우 종료하기 위해서
}
if(num == n-1){
break;
}
}
System.out.println(result);
bf.close();
}
static int find(int x){
if(x == root[x])
return root[x];
return root[x] = find(root[x]);
}
static void union(int x,int y){
x = find(x);
y = find(y);
if(x < y)
root[y] = x;
else{
root[x] = y;
}
}
}
class Node{
int v1;
int v2;
int c;
Node(int v1,int v2,int c){
this.v1 = v1;
this.v2 = v2;
this.c = c;
}
}'알고리즘 > 백준' 카테고리의 다른 글
| 백준 1175 (배달) - java (1) | 2024.01.05 |
|---|---|
| 백준 2616 (소형기관차) - java (1) | 2024.01.05 |
| 백준 16985 (Maaaaaaaaaze) - java (1) | 2023.12.21 |
| 백준 27211 (도넛 행성) - java (1) | 2023.12.19 |
| 백준 1368 (물대기) - java (0) | 2023.12.15 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준 #1584 #게임 #java #자바
- 백준 #12014 #주식 #자바 #java
- 백준 #13549 #숨바꼭질3
- 백준 #5721 #사탕 줍기 대회 #java #자바
- 백준 #치즈 #2638
- 백준 #
- 백준 #4963 #섬의 개수
- 백준 #16973 #직사각형 탈출
- 자바
- 자바 #JAVA
- 백준 #1987 #알파벳 #자바 #java
- 백준 #15686 #치킨 배달
- Java
- 백준
- 백준 #2636 #치즈
- 백준 #18405 #경쟁적 전염
- 백준 #2580 #스도쿠
- 올해보다
- 백준 #1325 #효율적인 해킹
- 백준 #25603 #짱해커 이동식 #java #자바
- 백준 #3980 #선발 명단
- 17394
- 백준 #인구 이동 #16234
- 백준 #다리 만들기 #2146
- 행복합시다.
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
- 백준 #1759 #암호 만들기
- 백준 #17940 #주식 #자바 #java
- 백준 #14863 #서울에서 경산까지 #java #자바
- 17218
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
글 보관함