문제
n개의 송전탑이 전선을 통해 하나의 트리 형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.
송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절대값)를 return 하도록 solution 함수를 완성해주세요.
제한사항
- n은 2 이상 100 이하인 자연수입니다.
- wires는 길이가 n-1인 정수형 2차원 배열입니다.
입출력 예
n | wires | result |
9 | [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] | 3 |
4 | [[1,2],[2,3],[3,4]] | 0 |
7 | [[1,2],[2,7],[3,7],[3,4],[4,5],[6,7]] | 1 |
입출력 예 설명
입출력 예 #1
- 다음 그림은 주어진 입력을 해결하는 방법 중 하나를 나타낸 것입니다.
- 4번과 7번을 연결하는 전선을 끊으면 두 전력망은 각 6개와 3개의 송전탑을 가지며, 이보다 더 비슷한 개수로 전력망을 나눌 수 없습니다.
- 또 다른 방법으로는 3번과 4번을 연결하는 전선을 끊어도 최선의 정답을 도출할 수 있습니다.
입출력 예 #2
- 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
- 2번과 3번을 연결하는 전선을 끊으면 두 전력망이 모두 2개의 송전탑을 가지게 되며, 이 방법이 최선입니다.
입출력 예 #3
- 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
- 3번과 7번을 연결하는 전선을 끊으면 두 전력망이 각각 4개와 3개의 송전탑을 가지게 되며, 이 방법이 최선입니다.
풀이
1. 전선 정보를 받아서 인접 행렬로 초기화
2. 선을 하나씩 끊어서 두 노드 간의 갯수차를 구하고 제일 적은 갯수 차이가 return 값( 선 끊을 시 두 노드의 갯수는 전력망 n개, 전력망 n-cnt개로 구성되어 두 전력망의 차이의 수는 절대값 n-(2*cnt) 개이다.)
3. BFS 함수를 통해 노드를 끊었을 때의 노드 차 최솟값을 비교
코드
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class WireExam {
static int[][] arr;
public static void main(String[] args) {
int n = 9;
int[][] w = {{1,3},
{2,3},
{3,4},
{4,5},
{4,6},
{4,7},
{7,8},
{7,9}};
solution(n,w);
}
public static int solution(int n, int[][] wires) {
int answer = n;
// 송전탑 개수 만큼 그래프 구성
arr= new int[n+1][n+1];
//1. 전선정보 를 받아서 인접행렬에 input 초기화
for(int i=0; i<wires.length; i++){
arr[wires[i][0]][wires[i][1]]=1;
arr[wires[i][1]][wires[i][0]]=1;
}
System.out.println(Arrays.deepToString(arr));
//2. 선을 하나씩 끊어보며 순회 동작 반복
int a, b;
for(int i=0; i<wires.length; i++){
a= wires[i][0];
b= wires[i][1];
//선을 하나 끊었을 때
arr[a][b]=0;
arr[b][a]=0;
//bfs
System.out.println("i : "+i+", answer : "+answer+", n : "+n+" , a : "+a);
answer= Math.min(answer, bfs(n, a));
System.out.println("answer : "+answer);
System.out.println("-------------");
//선 다시 복구
arr[a][b]=1;
arr[b][a]=1;
}
return answer;
}
public static int bfs(int n, int start){
boolean[] visit= new boolean[n+1];
int cnt=1;
Queue<Integer> queue= new LinkedList<>();
queue.offer(start);
while(!queue.isEmpty()){
int point= queue.poll();
visit[point]=true;
System.out.println("point : "+point);
//point와 연결된 애들 중에 방문한적 없는 노드 큐에 넣기
for(int i=1; i<=n; i++){
System.out.println("i : "+i);
if(visit[i]==true) continue;
if(arr[point][i]==1) {
queue.offer(i);
System.out.println("q : "+queue);
cnt++;
}
}
}
return (int)Math.abs(n-2*cnt); //cnt-(n-cnt);
}//bfs
}
'코테 > 탐색' 카테고리의 다른 글
[ 이분탐색 ] - 입국심사(중간값) (1) | 2024.01.01 |
---|---|
[ 완전 탐색] - 모음 사전(DFS, 재귀) (0) | 2023.12.27 |
[ 완전 탐색 ] - 피로도(DFS, 재귀) (0) | 2023.12.26 |
[ 완전 탐색 ] - 카펫(약수, 규칙) (0) | 2023.12.26 |
[ 완전 탐색 ] - 소수 찾기(Set, 재귀, Math.sqrt) (1) | 2023.12.26 |