Algorithm/Java
[프로그래머스/JAVA] 전력망을 둘로 나누기
dbfl9911
2024. 9. 18. 11:12
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/86971
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
- 문제 풀이
1. 그래프 초기화
import java.util.*;
class Solution {
static ArrayList<Integer>[] graph;
static int min;
// ... 생략
graph = new ArrayList[n+1];
min = Integer.MAX_VALUE; // 자바에서 표현할 수 있는 가장 큰 정수 값
for (int i = 1; i <= n; i++) {
graph[i] = new ArrayList<>();
// graph[1] = []
// graph[2] = []
// graph[3] = []
// graph[4] = []
}
+ 만약 ArrayList<Integer> graph = new ArrayList<>(); 형태로 작성하면,
이는 단일 ArrayList로 하나의 정점에만 연결된 값들을 저장하는 구조이다.
이 경우 전체 그래프를 표현하기보다는 하나의 정점과 그 정점에 연결된 인접 정점만 관리하는 용도로 사용됩니다.
// 단일 정점에 연결된 인접 정점을 저장하는 리스트
ArrayList<Integer> graph = new ArrayList<>();
// 인접 정점 추가 (1번 정점에서 연결된 정점들)
graph.add(2);
graph.add(3);
graph.add(5);
// 결과 출력
System.out.println(graph);
// 결과
// [2, 3, 5]
결과적으로 이 구조는 하나의 정점에 대한 정보만 포함하고 있어,
여러 정점을 관리하려면 ArrayList[] 배열이나 List<List<Integer>>와 같은 구조가 필요합니다.
2. 그래프에 연결 정보 추가
for (int i = 0; i < wires.length; i++) {
int v1 = wires[i][0];
int v2 = wires[i][1];
graph[v1].add(v2);
graph[v2].add(v1);
// wires = [[1, 2], [2, 3], [3, 4]] 일때,
// graph[1] = [2]
// graph[2] = [1, 3]
// graph[3] = [2, 4]
// graph[4] = [3]
}
3. 연결 정보를 하나씩 끊어서
for (int i = 0; i < wires.length; i++) {
int v1 = wires[i][0];
int v2 = wires[i][1];
// 전선을 끊음
graph[v1].remove(Integer.valueOf(v2));
graph[v2].remove(Integer.valueOf(v1));
문자열 -> 정수로 변환하려면,
(Integer.valueOf(), Integer.parseInt() 사용)
4. 끊어진 두 전력망 중 하나의 송전탑 개수들 세기
// DFS로 한 전력망의 송전탑 개수 세기
boolean[] visited = new boolean[n+1];
int cnt = dfs(1, visited);
// 연결된 송전탑의 개수를 세는 함수
static int dfs(int v, boolean[] visited) {
// v: 현재 방문 중인 송전탑 번호
visited[v] = true;
int cnt = 1;
for(int next : graph[v]) {
if (!visited[next]) {
cnt += dfs(next, visited);
}
}
return cnt;
}
5. 끊어진 두 전력망의 차이 구하기
// 다른 전력망의 송전탑 개수는 n - cnt
// Math.abs : 절댓값 구함
int diff = Math.abs(cnt - (n - cnt));
min = Math.min(min, diff);
// 전선 복구
graph[v1].add(v2);
graph[v2].add(v1);
}
return min;
- 정답 코드
import java.util.*;
class Solution {
static ArrayList<Integer>[] graph;
static int min;
// 연결된 송전탑의 개수를 세는 함수
static int dfs(int v, boolean[] visited) {
// v: 현재 방문 중인 송전탑 번호
visited[v] = true;
int cnt = 1;
for(int next : graph[v]) {
if (!visited[next]) {
cnt += dfs(next, visited);
}
}
return cnt;
}
public int solution(int n, int[][] wires) {
// 1. 그래프 초기화
graph = new ArrayList[n+1];
min = Integer.MAX_VALUE; // 자바에서 표현할 수 있는 가장 큰 정수 값
for (int i = 1; i <= n; i++) {
graph[i] = new ArrayList<>();
// graph[1] = []
// graph[2] = []
// graph[3] = []
// graph[4] = []
}
// 2. 그래프에 전선 정보 추가(양방향)
for (int i = 0; i < wires.length; i++) {
int v1 = wires[i][0];
int v2 = wires[i][1];
graph[v1].add(v2);
graph[v2].add(v1);
// wires = [[1, 2], [2, 3], [3, 4]] 일때,
// graph[1] = [2]
// graph[2] = [1, 3]
// graph[3] = [2, 4]
// graph[4] = [3]
}
// 3. 전선을 하나씩 끊어서 두 전력망의 송전탑 개수 차이 계산
for (int i = 0; i < wires.length; i++) {
int v1 = wires[i][0];
int v2 = wires[i][1];
boolean[] visited = new boolean[n+1];
// 전선을 끊음
graph[v1].remove(Integer.valueOf(v2));
graph[v2].remove(Integer.valueOf(v1));
// DFS로 한 전력망의 송전탑 개수 세기
int cnt = dfs(1, visited);
// 다른 전력망의 송전탑 개수는 n - cnt
// Math.abs : 절댓값 구함
int diff = Math.abs(cnt - (n - cnt));
min = Math.min(min, diff);
// 전선 복구
graph[v1].add(v2);
graph[v2].add(v1);
}
return min;
}
}
반응형