백준 1389 : 케빈 베이컨의 6단계 법칙

20309 단어 백준백준

문제

케빈 베이컨의 6단계 법칙에 의하면 지구에 있는 모든 사람들은 최대 6단계 이내에서 서로 아는 사람으로 연결될 수 있다. 케빈 베이컨 게임은 임의의 두 사람이 최소 몇 단계 만에 이어질 수 있는지 계산하는 게임이다.
BOJ 유저의 수와 친구 관계가 입력으로 주어졌을 때, 케빈 베이컨의 수가 가장 작은 사람을 구하는 프로그램을 작성하시오.

입력
첫째 줄에 유저의 수 N (2 ≤ N ≤ 100)과 친구 관계의 수 M (1 ≤ M ≤ 5,000)이 주어진다. 둘째 줄부터 M개의 줄에는 친구 관계가 주어진다. 친구 관계는 A와 B로 이루어져 있으며, A와 B가 친구라는 뜻이다. A와 B가 친구이면, B와 A도 친구이며, A와 B가 같은 경우는 없다. 친구 관계는 중복되어 들어올 수도 있으며, 친구가 한 명도 없는 사람은 없다. 또, 모든 사람은 친구 관계로 연결되어져 있다. 사람의 번호는 1부터 N까지이며, 두 사람이 같은 번호를 갖는 경우는 없다.

출력
첫째 줄에 BOJ의 유저 중에서 케빈 베이컨의 수가 가장 작은 사람을 출력한다. 그런 사람이 여러 명일 경우에는 번호가 가장 작은 사람을 출력한다.
BOJ1389

접근

BFS 문제라고 딱 생각되어 그 쪽으로 접근했다. 여태까지는 보통 이런 문제에서 인접행렬로 대충 떼우고 넘어간 경향이 있었지만, 오늘은 인접리스트로 데이터를 받아 구현했다.
N명의 유저에 대한 케빈 베이컨 수를 모두 구해야하기 때문에 BFS를 N번 반복했고, i번째 유저에 대해 케빈 베이컨 수를 구할 때, i가 아닌 나머지 유저들에게 걸리는 단계를 비트마스킹 형식으로 저장하여 그들을 더해 i번째 유저의 케빈 베이컨 수를 구했다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		String str = bf.readLine();
		StringTokenizer st = new StringTokenizer(str);
		Queue<Integer> q = new LinkedList<>();
		
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		
		int [] check = new int[n+1];
		int [] num = new int[n+1];
		
		ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
		for(int i = 0; i <= n; i++) {
			graph.add(new ArrayList<>());
		}
		
		for(int i = 0; i < m; i++) {
			str = bf.readLine();
			st = new StringTokenizer(str);
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			
			graph.get(a).add(b);
			graph.get(b).add(a);
		}
		
		int min = n * 7;
		int minNum = 0;
		
		for(int i = 1; i <= n; i++) {
			for(int j = 0; j < graph.get(i).size(); j++) {
				q.add(graph.get(i).get(j));
			}
			
			Arrays.fill(check, 0);
			Arrays.fill(num, 0);
			
			int count = 1;
			while(!q.isEmpty()) {
				int s = q.size();
				for(int k = 0; k < s; k++) {
					int tmp = q.poll();
					if(check[tmp] == 0) {
						check[tmp] = 1;
						num[tmp] = count;
						for(int j = 0; j < graph.get(tmp).size(); j++) {
							q.add(graph.get(tmp).get(j));
						}
					}
				}
				count++;
			}
			
			int result = 0;
			for(int j = 0; j < num.length; j++)
				result += num[j];
			result -= num[i];
			
			
			if(min > result) {
				min = result;
				minNum = i;
			}
		}
		
		System.out.println(minNum);
	}
}

좋은 웹페이지 즐겨찾기