티스토리 뷰
https://www.acmicpc.net/problem/1368
1368번: 물대기
첫 줄에는 논의 수 N(1 ≤ N ≤ 300)이 주어진다. 다음 N개의 줄에는 i번째 논에 우물을 팔 때 드는 비용 Wi(1 ≤ Wi ≤ 100,000)가 순서대로 들어온다. 다음 N개의 줄에 대해서는 각 줄에 N개의 수가 들어
www.acmicpc.net
문제
선주는 자신이 운영하는 N개의 논에 물을 대려고 한다. 물을 대는 방법은 두 가지가 있는데 하나는 직접 논에 우물을 파는 것이고 다른 하나는 이미 물을 대고 있는 다른 논으로부터 물을 끌어오는 법이다.
각각의 논에 대해 우물을 파는 비용과 논들 사이에 물을 끌어오는 비용들이 주어졌을 때 최소의 비용으로 모든 논에 물을 대는 것이 문제이다.
유형 : MST
접근 방식
- 직접 물을 주는 것과 간선을 통해 물을 흘려 보내는 것 2가지를 고려해야 하는 문제이다.
- 여기서 핵심은 물을 직접 주는 과정은 적어도 1번 이상 있어야 한다는 것이다.
- 그렇다면 직접 물을 주는 것의 가장 작은 값 1개로 풀어야 할까?
- 해당 지점의 간선 값이 크면 ? -> 완벽한 풀이가 될까?
- 2가지를 한번에 고려하는 것은 결국 해당 문제를 쉽게 해결할 수 없다.
- 하지만 간단하게 생각해보자 -> 직접 물을 주는 것을 0 번째 지점이라고 한다면?
- 가상의 0 번째 지점을 만들고 MST 만드는 것이다 !!!!
전체 코드
import java.util.*;
import java.io.*;
public class Main {
static int n = 0;
static int[][] d;
static int[] s;
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());
d = new int[n+1][n+1];
s = new int[n+1];
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
);
int total = 0;
for(int i=1;i<=n;i++){
int cur = Integer.parseInt(bf.readLine());
s[i] = cur;
pq.add(new Node(0,i,s[i]));
}
for(int i=1;i<=n;i++){
st = new StringTokenizer(bf.readLine(), " ");
for(int j=1;j<=n;j++){
d[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
pq.add(new Node(i,j,d[i][j]));
}
}
int count = 0;
while(!pq.isEmpty()){
Node cur = pq.poll();
if(find(cur.v1) != find(cur.v2)){
union(cur.v1,cur.v2);
count += 1;
total += cur.c;
}
if(count == n)
break;
}
System.out.println(total);
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; // 정점 1
int v2; // 정점 2
int c; // 간선 값
Node(int v1,int v2,int c){
this.v1 = v1;
this.v2 = v2;
this.c = c;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 16985 (Maaaaaaaaaze) - java (1) | 2023.12.21 |
---|---|
백준 27211 (도넛 행성) - java (1) | 2023.12.19 |
백준 11085 (군사 이동) -java (0) | 2023.12.15 |
백준 1445 (일요일 아침의 데이트) - java (0) | 2023.12.14 |
백준 17244 (아맞다우산) - java (1) | 2023.12.13 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준 #1325 #효율적인 해킹
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
- 백준 #13549 #숨바꼭질3
- 백준 #5721 #사탕 줍기 대회 #java #자바
- 백준 #1584 #게임 #java #자바
- 백준
- 백준 #치즈 #2638
- 자바 #JAVA
- 백준 #1987 #알파벳 #자바 #java
- 백준 #4963 #섬의 개수
- 17218
- 백준 #15686 #치킨 배달
- 백준 #25195 #yes or yes #java #자바
- 백준 #17940 #주식 #자바 #java
- 백준 #18405 #경쟁적 전염
- 자바
- 백준 #다리 만들기 #2146
- 백준 #16973 #직사각형 탈출
- 백준 #
- 17394
- Java
- 백준 #1759 #암호 만들기
- 백준 #인구 이동 #16234
- 백준 #3980 #선발 명단
- 백준 #25603 #짱해커 이동식 #java #자바
- 백준 #2580 #스도쿠
- 백준 #14863 #서울에서 경산까지 #java #자바
- 백준 #1727 #커플 만들기 #자바 #java
- 백준 #12014 #주식 #자바 #java
- 백준 #2636 #치즈
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
글 보관함