NullNull

[백준 P11403] 경로 찾기 Java 본문

알고리즘

[백준 P11403] 경로 찾기 Java

KYBee 2022. 10. 29. 18:16

P11403 경로찾기

 

11403번: 경로 찾기

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

www.acmicpc.net

문제

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

입력값

첫째 줄에 정점의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄부터 N개 줄에는 그래프의 인접 행렬이 주어진다. i번째 줄의 j번째 숫자가 1인 경우에는 i에서 j로 가는 간선이 존재한다는 뜻이고, 0인 경우는 없다는 뜻이다. i번째 줄의 i번째 숫자는 항상 0이다.

3
0 1 0
0 0 1
1 0 0
7
0 0 0 1 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
0 0 0 0 1 1 0
1 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 1 0 0 0 0

출력값

총 N개의 줄에 걸쳐서 문제의 정답을 인접행렬 형식으로 출력한다. 정점 i에서 j로 가는 경로가 있으면 i번째 줄의 j번째 숫자를 1로, 없으면 0으로 출력해야 한다.

1 1 1
1 1 1
1 1 1
1 0 1 1 1 1 1
0 0 1 0 0 0 1
0 0 0 0 0 0 0
1 0 1 1 1 1 1
1 0 1 1 1 1 1
0 0 1 0 0 0 1
0 0 1 0 0 0 0

알고리즘

최단 경로를 찾는 알고리즘을 사용해야 한다. 다익스트라, 벨만포드, 플로이드 워셜 등의 알고리즘 중에서 이 문제는 플로이드 워셜 알고리즘을 사용해야 한다. 그 이유는 출발지와 목적지가 명시되지 않았기 때문이다.

출발지와 목적지가 명시되지 않았다. 즉 특정 정점에서부터 다른 정점까지의 최단거리가 아닌, 모든 정점을 기준으로 탐색해야 한다. 이 경우에는 플로이드 워셜 알고리즘이 효과적이다.

플로이드 워셜 알고리즘은 중간에 거쳐가는 노드가 존재한다. 처음에는 중간에 아무런 노드가 거치지 않고 갈 때의 가중치를 담는다. 이후에 모든 정점을 차례대로 중간에 거치는 노드로 선택해보며 “출발지 → 중간 노드”와 “중간 노드 → 도착지” 의 합이 기록된 가중치보다 작다면 업데이트 한다.

아래 코드에서 가장 바깥 for 문 k가 중간에 거쳐 가는 노드를 뜻하고, i는 출발지 j는 도착지를 의미한다.

for (int k = 1; k <= N; k++) {
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            if (graph[i][k] != 0 && graph[k][j] != 0) {
                if (graph[i][j] == 0) {
                    graph[i][j] = 1;
                }
            }
        }
    }
}

코드

import java.util.*;
import java.io.*;

public class Main {

    static int N;
    static int[][] graph;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());

        graph = new int[N + 1][N + 1];

        StringTokenizer st;
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());

            for (int j = 1; j <= N; j++) {
                graph[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for (int k = 1; k <= N; k++) {
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= N; j++) {
                    if (graph[i][k] != 0 && graph[k][j] != 0) {
                        if (graph[i][j] == 0) {
                            graph[i][j] = 1;
                        }
                    }
                }
            }
        }

        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
                System.out.print(graph[i][j] + " ");
            }
            System.out.println();
        }
    }
}
Comments