[백준, BOJ 19542] 전단지 돌리기 (java)
Problem Solving/BOJ

[백준, BOJ 19542] 전단지 돌리기 (java)

728x90

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

 

19542번: 전단지 돌리기

현민이는 트리 모양의 길 위에서 오토바이를 타고 전단지를 돌리려고 한다. 현민이의 목표는 케니소프트에서 출발하여 모든 노드에 전단지를 돌리고, 다시 케니소프트로 돌아오는 것이다. 현민

www.acmicpc.net

728x90

메모리: 63,420 KB , 시간: 568  ms

사용 알고리즘: 깊이 우선 탐색, 그래프 이론, 그래프 탐색, 트리

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

    static int D;
    static ArrayList<ArrayList<Integer>> edges;
    static boolean[] visited;

    public static void main(String[] args) throws Exception{

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        // N := 노드의 개수, S := 케니소프트의 위치, D := 힘
        st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int S = Integer.parseInt(st.nextToken());
        D = Integer.parseInt(st.nextToken());

        // 연결관계
        edges = new ArrayList<>();
        for (int i = 0; i <= N; i++) {
            edges.add(new ArrayList<>());
        }

        int x, y;
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
            edges.get(x).add(y);
            edges.get(y).add(x);
        }

        // 방문 체크
        visited = new boolean[N + 1];

        int answer = dfs(S) * 2;
        if(answer <= 0) System.out.println(0);
        else System.out.println(answer);
    }

    private static int dfs(int node) { // node를 루트로 하는 서브 트리에서 전단지를 뿌리기 위해 이동해야 하는 최소 거리 리턴

        visited[node] = true;

        // 리프노드인지 확인
        int count = 0, next;
        for (int i = 0; i < edges.get(node).size(); i++) {
            next = edges.get(node).get(i);
            if(!visited[next]) count++;
        }
        if(count == 0) { // 리프 노드라면
            return D * -1;
        }

        int tmp;
        int ret = D * -1;
        for (int i = 0; i < edges.get(node).size(); i++) {
            next = edges.get(node).get(i);
            if(!visited[next]) {
                tmp = dfs(next);
                if(tmp < 0) ret = Math.max(ret, tmp + 1);
                else ret = ret <= 0 ? tmp + 1 : ret + tmp + 1;
            }
        }

        return ret;
    }
}
728x90