그래프 이론, 그래프 탐색, 최단 경로, 플로이드–워셜
경로 찾기 : Silver1
https://www.acmicpc.net/problem/11403
플로이드 와샬
플로이드 와샬 알고리즘에 대해 알지 못하는 상태라 먼저 해당 알고리즘에 대해 학습해보았다.
https://blog.naver.com/ndb796/221234427842
플로이드-와샬 알고리즘은 모든 정점 쌍 간의 최단 경로를 찾는 알고리즘이다.
여기서는 경로의 존재 여부를 확인하는 데 사용했다.
문제 이해
입력
- 첫 줄에 정점의 개수 N (1 ≤ N ≤ 100)
- 다음 N개의 줄에 걸쳐 N×N 크기의 인접 행렬이 주어진다.
- 행렬의 원소 값이 1이면 i에서 j로 가는 간선이 존재.
- 행렬의 원소 값이 0이면 i에서 j로 가는 간선이 존재하지 않음.
- i에서 i로 가는 경로는 항상 0으로 주어집니다.
출력
주어진 그래프에서 모든 정점 쌍 (i, j)에 대해 i에서 j로 가는 경로가 존재하면 1, 그렇지 않으면 0을 인접 행렬 형식으로 출력한다.
풀이 방법
초기화
주어진 인접 행렬을 초기화한다.
중간 정점을 통해 경로를 갱신
각 정점을 중간 정점으로 사용하여 경로를 갱신한다.
=> i에서 j로 직접 가는 경로가 없더라도, i에서 k를 거쳐 j로 가는 경로가 있을 수 있다. 이 과정을 반복하여 모든 경로 정보를 갱신한다.
풀이
import java.io.*;
import java.util.*;
public class Main {
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int N = Integer.parseInt(br.readLine());
int[][] graph = new int[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
graph[i][j] = Integer.parseInt(st.nextToken());
}
}
// 플로이드-와샬 알고리즘 적용
for (int k = 0; k < N; k++) { // 거쳐가는 정점
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (graph[i][k] == 1 && graph[k][j] == 1)
graph[i][j] = 1;
}
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
bw.write(graph[i][j] + " ");
}
bw.newLine();
}
bw.flush();
br.close();
bw.close();
}
}
입력을 아래와 같이 예를 들자면,
3
0 1 0
0 0 1
1 0 0
정점 0에서 정점 1로 가는 경로가 존재함
정점 1에서 정점 2로 가는 경로가 존재함
정점 2에서 정점 0으로 가는 경로가 존재함
거쳐가는 정점인 k = 0인 경우,
graph[2][0] == 1 && graph[0][1] == 1 이면, graph[2][1] = 1로 만들어준다. => 2에서 0을 거쳐서 1로 갈 수 있다.
거쳐가는 정점인 k = 1인 경우,
graph[0][1] == 1 && graph[1][2] == 1 이면, graph[0][2] = 1로 만들어준다. => 0에서 1를 거쳐서 2로 갈 수 있다.
거쳐가는 정점인 k = 2인 경우,
graph[1][2] == 1 && graph[2][0] == 1 이면, graph[1][0] = 1로 만들어준다. => 1에서 2를 거쳐서 0로 갈 수 있다.
그러므로,
최종 행렬의 형태는
1 1 1
1 1 1
1 1 1
이렇게 된다.
'코딩테스트 > programming_JAVA' 카테고리의 다른 글
[Java] baekjoon_21736 : 헌내기는 친구가 필요해 (0) | 2024.05.16 |
---|---|
[Java] baekjoon_2630 : 색종이 만들기 (1) | 2024.03.02 |
[Java] baekjoon_1271 : 엄청난 부자2 (1) | 2024.03.01 |
[Java] baekjoon_11286 : 절댓값 힙 (1) | 2024.02.16 |
[Java] baekjoon_1541 : 잃어버린 괄호 (1) | 2024.02.13 |