[백준]#16437 양 구출 작전

SeungBird·2021년 5월 21일
0

⌨알고리즘(백준)

목록 보기
338/401

문제

N개의 섬으로 이루어진 나라가 있습니다. 섬들은 1번 섬부터 N번 섬까지 있습니다.

1번 섬에는 구명보트만 있고 다른 섬에는 양들 또는 늑대들이 살고 있습니다.

늘어나는 늑대의 개체 수를 감당할 수 없던 양들은 구명보트를 타고 늑대가 없는 나라로 이주하기로 했습니다.

각 섬에서 1번 섬으로 가는 경로는 유일하며 i번 섬에는 pi번 섬으로 가는 다리가 있습니다.

양들은 1번 섬으로 가는 경로로 이동하며 늑대들은 원래 있는 섬에서 움직이지 않고 섬으로 들어온 양들을 잡아먹습니다. 늑대는 날렵하기 때문에 섬에 들어온 양을 항상 잡을 수 있습니다. 그리고 늑대 한 마리는 최대 한 마리의 양만 잡아먹습니다.

얼마나 많은 양이 1번 섬에 도달할 수 있을까요?

입력

첫 번째 줄에 섬의 개수 N (2 ≤ N ≤ 123,456) 이 주어집니다.

두 번째 줄부터 N-1개에 줄에 2번 섬부터 N번 섬까지 섬의 정보를 나타내는 ti, ai, pi (1 ≤ ai ≤ 109, 1 ≤ pi ≤ N) 가 주어집니다.

ti가 'W' 인 경우 i번 섬에 늑대가 ai마리가 살고 있음을, ti가 'S'인 경우 i번 섬에 양이 ai마리가 살고 있음을 의미합니다. pi는 i번째 섬에서 pi번 섬으로 갈 수 있는 다리가 있음을 의미합니다.

출력

첫 번째 줄에 구출할 수 있는 양의 수를 출력합니다.

예제 입력 1

4
S 100 3
W 50 1
S 10 1

예제 출력 1

60

예제 입력 2

7
S 100 1
S 100 1
W 100 1
S 1000 2
W 1000 2
S 900 6

예제 출력 2

1200

풀이

이 문제는 bfs(너비 우선 탐색) 알고리즘을 이용해서 트리를 구성한 뒤에 dfs(깊이 우선 탐색) 알고리즘을 이용해서 답을 구할 수 있었다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static char[] types;
    static int[] animals;
    static ArrayList<Integer>[] tree;
    static ArrayList<Integer>[] map;

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        types = new char[N+1];
        animals = new int[N+1];
        tree = new ArrayList[N+1];
        map = new ArrayList[N+1];
        for(int i=1; i<=N; i++) {
            map[i] = new ArrayList<>();
            tree[i] = new ArrayList<>();
        }

        for(int i=2; i<=N; i++) {
            String[] input = br.readLine().split(" ");
            char t = input[0].charAt(0);
            int a = Integer.parseInt(input[1]);
            int p = Integer.parseInt(input[2]);

            types[i] = t;
            animals[i] = a;
            map[i].add(p);
            map[p].add(i);
        }

        make_tree(N);

        System.out.println(count(1));
    }

    public static long count(int idx) {
        long sum = 0;

        for(int next : tree[idx]) {
           sum += count(next);
        }

        if(types[idx]=='S')
            return sum+=animals[idx];
        else
            return Math.max(sum-animals[idx], 0);
    }

    public static void make_tree(int N) {
        Queue<Integer> queue = new LinkedList<>();
        boolean[] visited = new boolean[N+1];
        visited[1] = true;
        queue.add(1);

        while(!queue.isEmpty()) {
            int temp = queue.poll();

            for(int next : map[temp]) {
                if(visited[next]) continue;
                visited[next] = true;
                tree[temp].add(next);
                queue.add(next);
            }
        }
    }
}
profile
👶🏻Jr. Programmer

0개의 댓글