• 문제 링크
1389번: 케빈 베이컨의 6단계 법칙
첫째 줄에 유저의 수 N (2 ≤ N ≤ 100)과 친구 관계의 수 M (1 ≤ M ≤ 5,000)이 주어진다. 둘째 줄부터 M개의 줄에는 친구 관계가 주어진다. 친구 관계는 A와 B로 이루어져 있으며, A와 B가 친구라는 뜻
www.acmicpc.net
• 풀이 과정
[백준] 11404 플로이드 - Graph Theory / Java
• 문제 링크 11404번: 플로이드 첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는
graycode.tistory.com
위 문제와 유사한 구조의 Floyd-Warshall 알고리즘 문제이다.
모든 노드간 최단 경로를 구하되, 노드간 몇 번 이동했는지만 구하면 되므로
무향 그래프의 가중치를 1로 지정하여 각 경로의 최소 이동 횟수를 구한다.
이 후 각각의 노드를 시작점으로 하는 모든 경로의 이동 횟수의 합을 최소값으로 갱신하고,
해당 노드의 번호를 정답으로써 출력한다.
• 풀이 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static int n;
static int[][] dist;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
dist = new int[n + 1][n + 1];
int inf = 5001;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j)
continue;
else
dist[i][j] = inf;
}
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int src = Integer.parseInt(st.nextToken());
int dest = Integer.parseInt(st.nextToken());
dist[src][dest] = dist[dest][src] = 1;
}
floydWarshall();
int minCnt = inf;
int res = 0;
for (int i = 1; i <= n; i++) {
int cnt = 0;
for (int j = 1; j <= n; j++)
cnt += dist[i][j];
if (minCnt > cnt) {
minCnt = cnt;
res = i;
}
}
bw.write(res + "\n");
bw.flush();
}
private static void floydWarshall() {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
if (i == k)
continue;
for (int j = 1; j <= n; j++) {
if (j == i || j == k)
continue;
if (dist[i][j] > dist[i][k] + dist[k][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
}
아래의 코드는 BFS 를 통한 풀이로,
Queue 를 통해 특정 시작점에서 파생될 수 있는 모든 경로를 방문 여부를 확인하며 탐색한다.
이렇게 총 이동 횟수를 누적 및 반환하고, 이 중 최소 이동 횟수를 가지는 노드의 번호를 정답으로써 출력한다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int[] dist;
static List<Integer>[] list;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
dist = new int[n + 1];
list = new ArrayList[n + 1];
for (int i = 1; i <= n; i++)
list[i] = new ArrayList<>();
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int src = Integer.parseInt(st.nextToken());
int dest = Integer.parseInt(st.nextToken());
list[src].add(dest);
list[dest].add(src);
}
int minCnt = Integer.MAX_VALUE;
int res = 0;
for (int i = 1; i <= n; i++) {
int cnt = bfs(i);
if (minCnt > cnt) {
minCnt = cnt;
res = i;
}
}
bw.write(res + "\n");
bw.flush();
}
private static int bfs(int source) {
Queue<Integer> q = new LinkedList<>();
q.offer(source);
Arrays.fill(dist, -1);
dist[source] = 0;
int cnt = 0;
while (!q.isEmpty()) {
int src = q.poll();
for (int dest : list[src]) {
if (dist[dest] != -1)
continue;
dist[dest] = dist[src] + 1;
cnt += dist[dest];
q.offer(dest);
}
}
return cnt;
}
}
'Problem Solving > Baekjoon' 카테고리의 다른 글
[백준] 2193 이친수 - Dynamic Programming / Java (0) | 2022.08.24 |
---|---|
[백준] 10844 쉬운 계단 수 - Dynamic Programming / Java (0) | 2022.08.23 |
[백준] 11404 플로이드 - Graph Theory / Java (0) | 2022.08.21 |
[백준] 1753 최단경로 - Graph Theory / Java (0) | 2022.08.20 |
[백준] 1916 최소비용 구하기 - Graph Theory / Java (0) | 2022.08.19 |
댓글