티스토리 뷰
https://www.acmicpc.net/problem/13905
13905번: 세부
첫 번째 줄에는 섬에 존재하는 집의 수 N(2≤N≤100,000)와 다리의 수 M(1≤M≤300,000)이 주어진다. 두 번째 줄에는 숭이의 출발 위치(s)와 혜빈이의 위치(e)가 주어진다. (1≤s, e≤N, s≠e). 다음 M개의 줄
www.acmicpc.net

문제
빼빼로 데이를 맞아 혜빈이와 숭이는 세부에 있는 섬에 놀러 갔다. 섬은 바다 위에 떠다니는 집과 집들을 연결하는 오크나무로 되어있는 다리로 이뤄져 있다. 숭이는 혜빈이에게 깜짝 이벤트를 해주기 위해 섬 관리자에게 혜빈이를 이벤트장소에 머물게 해달라고 하였다. 이벤트 당일 날 숭이는 금으로 된 빼빼로들을 들고 이벤트 장소로 이동하려 했다. 하지만 아뿔싸! 각 다리마다 다리 위를 지날 수 있는 무게 제한이 존재했다. 비싼 금빼빼로를 가면서 버리기 아깝던 숭이는 자신이 머물던 집에서 자신이 혜빈이에게 갈 수 있는 최대한의 금빼빼로만을 들고 가려고 한다. 따라서 숭이는 인공위성조차 해킹할 수 있는 당신에게 혜빈이에게 들고 갈 수 있는 최대한의 금빼빼로 개수를 알려달라고 부탁했다. 당신은 인공위성을 해킹하여 집들의 번호와 다리의 무게제한을 알아내었다. 이 정보를 가지고 빨리 숭이를 도와주자.
(금빼빼로 하나의 무게는 1이고, 숭이의 몸무게는 고려하지 않는다.)
유형 : MST
접근 방식
- 보통 위의 문제를 보고 최대 유량을 생각할 수 있다. 하지만 MST를 이용해서 충분히 해결할 수 있는 문제이다.
- 우선 위의 문제에서 중요한 점은 MST를 만드는 것이 목적이 아니란 것이다 !
- MST를 만드는 과정이 문제를 푸는 핵심인 것이다.
- 우선 가장 많은 양의 빼빼로를 가져가기 위해서는 무게 단위가 큰 다리를 선택해야 한다.
- MST의 기존 방식과 반대인 무게 단위가 큰 간선부터 선택하도록 한다.
- 선택되는 간선의 무게는 진행될수록 작아질 것이다. -> 해당 값을 계속 초기화 하도록 한다.
- 언제까지 반복해야 할까?
- 가장 중요한 접근이다. 결국 출발지와 목적지가 이어진 순간 : find(s) == find(e)
- 결국 출발지와 목적지가 이어졌을 때 선택된 간선이 정답이다. -> 여태까지 사용한 간선들 중에 무게가 가장 작을 것이기 때문 !
전체 코드
import java.io.*;
import java.util.*;
public class Main {
static int n = 0;
static int m = 0;
static int s = 0;
static int e = 0;
static int[] root;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
root = new int[n+1];
for(int i=1;i<=n;i++){
root[i] = i;
}
st = new StringTokenizer(br.readLine(), " ");
s = Integer.parseInt(st.nextToken());
e = Integer.parseInt(st.nextToken());
PriorityQueue<Node> pq = new PriorityQueue<>(
(x,y) -> y.c - x.c
);
for(int i=1;i<=m;i++){
st = new StringTokenizer(br.readLine(), " ");
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
pq.add(new Node(v1,v2,c));
}
int min = 1000001;
while(!pq.isEmpty()){
Node cur = pq.poll();
if(find(cur.v1) != find(cur.v2))
{
union(cur.v1,cur.v2);
min = Math.min(min,cur.c);
}
if(find(s) == find(e)){
System.out.println(min);
return;
}
}
System.out.println(0);
br.close();
}
static int find(int x){
if(root[x] == 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;
}
}'알고리즘 > 백준' 카테고리의 다른 글
| 백준 17352 (여러분의 다리가 되어 드리겠습니다) - java (0) | 2023.11.02 |
|---|---|
| 백준 11509 (풍선 맞추기) - java (1) | 2023.11.01 |
| 백준 1990 (소수인팰린드롬) - java (1) | 2023.10.30 |
| 백준 2436 (공약수) - java (0) | 2023.10.29 |
| 백준 2023 (신기한 소수) - java (0) | 2023.10.26 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준 #1987 #알파벳 #자바 #java
- 백준 #다리 만들기 #2146
- 백준 #16973 #직사각형 탈출
- 백준 #18405 #경쟁적 전염
- 백준 #1759 #암호 만들기
- 백준 #14863 #서울에서 경산까지 #java #자바
- 백준 #1325 #효율적인 해킹
- 자바
- 백준 #1584 #게임 #java #자바
- Java
- 17218
- 올해보다
- 백준 #2636 #치즈
- 백준 #12014 #주식 #자바 #java
- 백준 #15686 #치킨 배달
- 백준 #3980 #선발 명단
- 백준 #2580 #스도쿠
- 백준
- 백준 #25603 #짱해커 이동식 #java #자바
- 백준 #5721 #사탕 줍기 대회 #java #자바
- 행복합시다.
- 백준 #4963 #섬의 개수
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
- 백준 #13549 #숨바꼭질3
- 자바 #JAVA
- 백준 #
- 17394
- 백준 #인구 이동 #16234
- 백준 #17940 #주식 #자바 #java
- 백준 #치즈 #2638
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
글 보관함