본문 바로가기

알고리즘/백준

13023 - ABCDE[G5]

문제

문제

 

BOJ 알고리즘 캠프에는 총 N명이 참가하고 있다. 사람들은 0번부터 N-1번으로 번호가 매겨져 있고, 일부 사람들은 친구이다.

오늘은 다음과 같은 친구 관계를 가진 사람 A, B, C, D, E가 존재하는지 구해보려고 한다.

  • A는 B와 친구다.
  • B는 C와 친구다.
  • C는 D와 친구다.
  • D는 E와 친구다.

위와 같은 친구 관계가 존재하는지 안하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 사람의 수 N (5 ≤ N ≤ 2000)과 친구 관계의 수 M (1 ≤ M ≤ 2000)이 주어진다.

둘째 줄부터 M개의 줄에는 정수 a와 b가 주어지며, a와 b가 친구라는 뜻이다. (0 ≤ a, b ≤ N-1, a ≠ b) 같은 친구 관계가 두 번 이상 주어지는 경우는 없다.

출력

문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

 

풀이

 

결국 문제의 핵심은 Depth 5 이상인 노드를 찾는 것이다.

이것을 위해 입력값에서 Node Class를 정의하고 BackTracking을 사용하여 깊이 5 이상을 탐색하며, 가지치기를 수행하였다. (여기서 Node를 입력받을 시, 양방향으로 관계를 이어주어야 한다.)

 

 

이 과정에서 초기 입력 시 한번도 언급되지 않는 Node가 Null로 선언되는 자잘한 이슈가 있었다.

다음부터는 입력값 시 명시적으로 노드를 초기화해주어야 할 것 같다.

 

자세한 내용은 코드를 참조할 것

코드

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

public class Main {
    static int N, M;
    static boolean[] check;
    static int checkCnt;
    static Node[] nodeArr;
    static boolean isRemain = false;
    public static void main(String[] args) {
        input();
        //logging();
        for(int i = 0; i < N; i++) {
            check = new boolean[N]; //초기화
            backTracking(i); //logic
            if (isRemain) {
                System.out.println(1);
                return;
            }
        }
        System.out.println(0);

    }

    static void backTracking(int idx) {
        check[idx] = true;
        if (isRemain || checkLength()) { //기저조건
            isRemain = true;
            return;
        }

        for(int i = 0; i < nodeArr[idx].friends.size(); i++) {
            int next = nodeArr[idx].friends.get(i);
            if(check[next]) continue;
            backTracking(next);
            check[next] = false; //다시 false 처리
        }
    }

    static boolean checkLength() {
        int cnt = 0;
        for(boolean now : check) {
            if (now) cnt++;
            if (cnt >= 5) return true;
        }
        return false;
    }

    static void logging() {
        for(int i = 0; i < nodeArr.length; i++) {
            try{
                System.out.println(i + " : " + Arrays.toString(nodeArr[i].friends.toArray()));
            } catch (NullPointerException e) {
                System.out.println("NULL");
            }
        }
    }
    static void input() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(br.readLine());
            N = Integer.parseInt(st.nextToken());
            M = Integer.parseInt(st.nextToken());
            check = new boolean[N];
            nodeArr = new Node[N];
            for (int i = 0; i < N; i++) { // 모든 노드를 초기화하는 과정 추가 (99%에서 NullException 발생)
                nodeArr[i] = new Node(i);
            }

            for(int i = 0; i < M; i++) {
                st = new StringTokenizer(br.readLine());
                int num = Integer.parseInt(st.nextToken());
                int friend = Integer.parseInt(st.nextToken());
                //내 쪽 추가
                if(nodeArr[num] == null) nodeArr[num] = new Node(num, friend);
                else nodeArr[num].friends.add(friend);

                //친구 쪽 추가
                if(nodeArr[friend] == null) nodeArr[friend] = new Node(friend, num);
                else nodeArr[friend].friends.add(num);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class Node {
    int num;
    List<Integer> friends = new ArrayList<>();

    public Node (int num) { this.num = num;}
    public Node (int num, int friend) {
        this.num = num;
        friends.add(friend);
    }
}

'알고리즘 > 백준' 카테고리의 다른 글

15683 - 감시[G4]  (0) 2024.04.12
5972 - 택배 배송(G5)  (0) 2024.03.30
단어 뒤집기 2 - 17413[S3]  (0) 2024.03.21
경로 찾기 - 11403[S1]  (1) 2024.01.09
15961 - 회전 초밥[G4]  (1) 2024.01.07