[BOJ1414] 불우이웃돕기 (프림, 최소 신장트리, 그리디)알고리즘/탐욕(그리디)2023. 9. 6. 17:00
Table of Contents
반응형
문제 링크
https://www.acmicpc.net/problem/1414
문제 풀이
- 프림 알고리즘(최소 신장트리) 사용하여 풀이
- 시간 복잡도 : O(ElogV)
절차
1) 모든 컴퓨터(노드)를 연결하는 최소 랜선 길이(비용)을 구한다.
2) 다솜이가 가진 총 랜선 길이에서 최소 랜선 길이 뺀 나머지를 기부 한다
알파벳이 소문자인지, 대문자인지 구분하는 방법이 조금 애매했는데
이번 문제를 통해 Character 클래스에 유용한 메서드를 알게 되었다.
// 알파벳 -> 숫자 ( a ~ z : 1 ~26, A ~ z : 27 ~ 52)
private static int convertAlphabet(char alphabet) {
if(Character.isLowerCase(alphabet)) return alphabet - 'a' + 1;
else if(Character.isUpperCase(alphabet)) return alphabet - 'A' + 27;
return 0;
}
제출 코드
import java.util.*;
import java.io.*;
public class Main {
static StringBuilder sb = new StringBuilder();
static int N;
static List<Edge>[] adj;
static class Edge implements Comparable<Edge> {
int idx;
int cost;
public Edge(int idx, int cost) {
this.idx = idx;
this.cost = cost;
}
@Override
public int compareTo(Edge other) {
return cost - other.cost; // 내림차순
}
}
private static int convertAlphabet(char alphabet) {
if(Character.isLowerCase(alphabet)) return alphabet - 'a' + 1;
else if(Character.isUpperCase(alphabet)) return alphabet - 'A' + 27;
return 0;
}
static void input() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
adj = new ArrayList[N + 1];
for(int i = 1; i <= N; i++) adj[i] = new ArrayList<>();
int totalLen = 0;
for(int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
char[] line = st.nextToken().toCharArray();
for(int j = 1; j <= N; j++) {
if(line[j - 1] == '0') continue;
int cost = convertAlphabet(line[j - 1]);
adj[i].add(new Edge(j, cost));
adj[j].add(new Edge(i, cost));
totalLen += cost;
}
}
// 시작 노드를 i 로 노드를 모두 연결하는 최소 비용 찾는다
int result = Integer.MAX_VALUE;
for(int i = 1; i <= N; i++) {
result = Math.min(result, pro(i));
}
// 최소 비용을 제외한 나머지 랜선을 기부한다
if(result == -1) sb.append("-1");
else sb.append(totalLen - result);
System.out.println(sb);
}
static int pro(int start) {
Queue<Edge> que = new PriorityQueue<>();
que.add(new Edge(start, 0));
boolean[] visit = new boolean[N + 1];
int result = 0;
int edgeCnt = 0;
while(!que.isEmpty()) {
Edge cur = que.poll();
if(visit[cur.idx]) continue;
visit[cur.idx] = true;
result += cur.cost;
edgeCnt += 1;
for(Edge next : adj[cur.idx]) {
if(visit[next.idx]) continue;
que.add(next);
}
}
return edgeCnt == N ? result : -1;
}
public static void main(String[] args) throws Exception {
input();
}
}
반응형
'알고리즘 > 탐욕(그리디)' 카테고리의 다른 글
[BOJ20010] 악덕 영주 혜유 (크루스칼, 프림, MST, 최소신장트리, 트리의 지름) (0) | 2023.09.07 |
---|---|
[BOJ1368] 물대기 (프림 알고리즘, 최소 신장 트리, 그리디) (0) | 2023.09.06 |
[BOJ4386] 별자리 만들기 (프림 알고리즘, 최소신장트리, MST) (0) | 2023.09.06 |
[BOJ6497] 전력난 (크루스칼, 프림, 최소 신장트리, MST) (0) | 2023.09.06 |
[BOJ1774] 우주신과의 교감 (그리디, 크루스칼, MST, 최소신장트리) (0) | 2023.09.05 |
@leejinwoo1126 :: 천천히 하나씩
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!