코딩 테스트(Coding Test)/백준
[백준] 2260번 : 회장 뽑기 - 자바(Java)
다문다뭉
2024. 11. 19. 18:14
Problem 🔒
문제
https://www.acmicpc.net/problem/2660
월드컵 축구의 응원을 위한 모임에서 회장을 선출하려고 한다. 이 모임은 만들어진지 얼마 되지 않았기 때문에 회원 사이에 서로 모르는 사람도 있지만, 몇 사람을 통하면 모두가 서로 알 수 있다. 각 회원은 다른 회원들과 가까운 정도에 따라 점수를 받게 된다.
예를 들어 어느 회원이 다른 모든 회원과 친구이면, 이 회원의 점수는 1점이다. 어느 회원의 점수가 2점이면, 다른 모든 회원이 친구이거나 친구의 친구임을 말한다. 또한 어느 회원의 점수가 3점이면, 다른 모든 회원이 친구이거나, 친구의 친구이거나, 친구의 친구의 친구임을 말한다.
4점, 5점 등은 같은 방법으로 정해진다. 각 회원의 점수를 정할 때 주의할 점은 어떤 두 회원이 친구사이이면서 동시에 친구의 친구사이이면, 이 두사람은 친구사이라고 본다.
회장은 회원들 중에서 점수가 가장 작은 사람이 된다. 회장의 점수와 회장이 될 수 있는 모든 사람을 찾는 프로그램을 작성하시오.
입력
입력의 첫째 줄에는 회원의 수가 있다. 단, 회원의 수는 50명을 넘지 않는다. 둘째 줄 이후로는 한 줄에 두 개의 회원번호가 있는데, 이것은 두 회원이 서로 친구임을 나타낸다. 회원번호는 1부터 회원의 수만큼 붙어 있다. 마지막 줄에는 -1이 두 개 들어있다.
출력
첫째 줄에는 회장 후보의 점수와 후보의 수를 출력하고, 두 번째 줄에는 회장 후보를 오름차순으로 모두 출력한다.
더보기
예제 입력 1
5
1 2
2 3
3 4
4 5
2 4
5 3
-1 -1
예제 출력 1
2 3
2 3 4
Approach 1 ⭕ - BFS 일반
- 회원 마다 점수 구하기(BFS 메서드)
- 회원이 N명이라면, 1번 회원부터 N번 회원까지 점수를 구한다.
- 각 회원에서 다른 모든 회원까지의 최단 거리를 BFS를 활용하여 구하고, 그 중 가장 먼 거리를 점수(s)로 저장한다.
- 나는 방문배열(visit)에 해당 회원까지의 거리를 저장하여 방문 처리했지만, 그렇게 하지 않고 boolean 형태로 처리해도 될 것 같다.
- 회원 중 점수가 가장 낮은 사람들을 찾아 회장 후보로 선정하기
- 회원들의 점수 배열(score)에서 가장 낮은 점수를 min 변수에 저장한다.
- 점수가 min과 같은 회원들을 찾으며, 후보의 수와 후보 번호를 저장한다.
Solution 💡
import java.util.*;
public class 회장뽑기 {
static int N, score[], visit[];
static ArrayList<ArrayList<Integer>> list = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt()+1;
score = new int[N];
visit = new int[N];
for(int i=0; i<N; i++){list.add(new ArrayList<>());}
while(true){
int u = sc.nextInt();
int v = sc.nextInt();
if(u==-1 && v==-1) break;
list.get(u).add(v);
list.get(v).add(u);
}
// 후보 1번부터 N번까지 점수 구하기
for(int i=1; i<N; i++){
for(int j=0; j<N; j++){visit[j]=-1;}
BFS(i);
}
// 최소값 찾기(회장 후보의 점수)
int min = 100;
for(int i=1; i<N; i++){min = Math.min(min, score[i]);}
// 회장 후보 찾기
int cnt = 0; // 회장 후보 수
StringBuilder sb = new StringBuilder();
for(int i=1; i<N; i++){
if(score[i]==min){
cnt++;
sb.append(i).append(" "); // 회장 후보 인덱스 저장
}
}
System.out.println(min + " " + cnt);
System.out.println(sb);
}
public static void BFS(int node){
int s = 0; // 거리
Queue<Integer> q = new LinkedList<>();
q.add(node);
visit[node] = s; // 시작점은 0으로
// 큐가 빌 때까지 반복
while(!q.isEmpty()){
// 동일한 거리에 있는 회원들만 처리하기 위해서, 큐의 크기만큼만 반복
int qsize = q.size();
s++; // 거리 1 증가
for(int i=0; i<qsize; i++){
int next = q.poll(); // 인접한 노드를 꺼내서
for(int j : list.get(next)){
if(visit[j]==-1){
visit[j] = s; // 방문하지 않았으면 방문하고
q.add(j); // 큐에 저장한다
}
}
}
}
score[node] = s-1; // 가장 먼 거리를 회원의 점수로 저장한다
}
}