내가 개발해볼게!!

[BOJ] 백준 11403번: 경로 찾기(Java) 본문

Algorithm/BOJ

[BOJ] 백준 11403번: 경로 찾기(Java)

보송송희 2023. 8. 25. 00:33

 

https://www.acmicpc.net/problem/11403

 

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이다.

 

출력

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

 

난이도

실버 1

 

 Sol

BFS(너비 우선 탐색) - 1번부터 N번까지의 정점과 인접한 노드들을 확인하면서 인접행렬을 채워나간다

  • 1번 정점에서 갈 수 있는 노드들을 큐에 담는다
  • 큐에 담긴 각 노드에서 갈 수 있는 노드를 체크해 큐에 담고, 확인한 노드는 큐에서 제거한다
  • 인접한 노드들을 발견할 때마다 인접행렬의 값을 업데이트한다
  • 1~3 과정을 1번 정점부터 N번 정점까지 반복한다
public class BOJ11403 {
    static int N; // 정점의 개수
    static int[][] near; // 인접행렬
    static Queue<Integer> queue = new LinkedList<>();

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer token = new StringTokenizer(bf.readLine());
        N = Integer.parseInt(token.nextToken());
        near = new int[N][N];

        for(int i=0; i<N; i++){
            token = new StringTokenizer(bf.readLine());

            for(int j=0; j<N; j++)
                near[i][j] = Integer.parseInt(token.nextToken());
        }
        // input

        int num; // 임시로 쓸 변수

        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if(near[i][j]==1)
                    queue.add(j); // i에서 갈 수 있는 노드들을 큐에 추가

                while(!queue.isEmpty()){ // BFS를 돌리면서 i와 인접한 노드와 또 인접한 노드들을 체크한다
                    num = queue.poll(); // 확인한 노드를 큐에서 제거한다
                    search(i, num);
                }
            }
        }
        // operation

        for(int[] arr : near){
            for(int i : arr) System.out.print(i + " ");
            System.out.println();
        }
        // output
    }

    // BFS
    static void search(int now, int num){ // 현재 위치한 노드 now, now에 인접한 노드 num
        near[now][num] = 1; // 인접행렬에 반영
        for(int i=0; i<N; i++){
            if(near[num][i]==1 && near[now][i] != 1){
                // 현재 노드와의 인접행렬 값에 1이 들어가 있는 노드는 이미 검사를 끝낸 노드이기 때문에 조건문으로 걸러낸다. 조건을 안 주면 무한루프에 빠진다
                // 예: near[1][2]와 near[2][1]을 반복적으로 돌 수 있다
                queue.add(i); // now에 인접한 노드와 인접해 있는 노드를 큐에 추가한다
            }
        }
    }
}

 

😅

BFS 메소드 내의 조건문에 near[now][i] != 1을 주지 않으면 i번째 노드와 i+1번째 노드 사이에서 무한 루프에 빠진다.