ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 1238 파티
    ALGORITHM/BOJ 2021. 1. 31. 20:08

    www.acmicpc.net/problem/1238

     

    1238번: 파티

    첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), X가 공백으로 구분되어 입력된다. 두 번째 줄부터 M+1번째 줄까지 i번째 도로의 시작점, 끝점, 그리고 이 도로를 지나는데 필요한 소요시간 Ti가 들어

    www.acmicpc.net

    2021-01-30


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.PriorityQueue;
    import java.util.StringTokenizer;
     
    public class Main1238 {
        public static int N, M, X, dist[], rdist[];
        public static List<List<Party>> list, rlist;
        
        static class Party implements Comparable<Party> {
            int v;
            int d;
            
            public Party(int v, int d) {
                this.v = v;
                this.d = d;
            }
     
            @Override
            public int compareTo(Party o) {
                return this.d - o.d;
            }
        }
        public static void solve(List<List<Party>> p, int di[]) {
            boolean vtd[] = new boolean[N+1];
            PriorityQueue<Party> pq = new PriorityQueue<>();
            di[X] = 0;
            pq.add(new Party(X, 0));
            
            while(!pq.isEmpty()) {
                int cur = pq.poll().v;
                
                if(vtd[cur]) continue// 방문한적이 있다면 넘어가고 
                vtd[cur] = true;
                
                for(Party pa: p.get(cur)) { // cur와 연결된 간선들을 체크한다.
                    if(di[pa.v] > di[cur] + pa.d) { // 그 간선의 현재 dist값보다, dist[cur] + 연결된 값이 더 작으면 교체한다.
                        di[pa.v] = di[cur] + pa.d; 
                        pq.add(new Party(pa.v, di[pa.v]));
                    }
                }
            }
        }
        
        public static void main(String[] args) throws Exception {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(bf.readLine());
            N = Integer.parseInt(st.nextToken());
            M = Integer.parseInt(st.nextToken());
            X = Integer.parseInt(st.nextToken());
            
            list = new ArrayList<>();
            rlist = new ArrayList<>();
            
            dist = new int[N+1]; // 파티에서 돌아오는 경우
            rdist = new int[N+1]; // 집에서 파티를 참석하러 가는 경우
            
            // 초기화 
            for(int i = 0; i <= N; i++) {
                list.add(new ArrayList<>());
                rlist.add(new ArrayList<>());
                dist[i] = 987654321;
                rdist[i] = 987654321;
            }
            
            for(int i = 0; i < M; i++) {
                st = new StringTokenizer(bf.readLine());
                int a = Integer.parseInt(st.nextToken());
                int b = Integer.parseInt(st.nextToken());
                int c = Integer.parseInt(st.nextToken());
                
                list.get(a).add(new Party(b, c));
                rlist.get(b).add(new Party(a, c));
            }
            
            
            solve(list, dist);
            solve(rlist, rdist); 
            
            int answer = 0;
            for(int i = 1; i <= N; i++
                answer = Math.max(answer, (dist[i] + rdist[i]));
            
            System.out.println(answer);
        }
    }
     
    cs

    #문제풀이

    다익스트라 알고리즘 문제이다. 

     

    맨 처음에 플로이드-와샬을 생각했지만, 그렇게 풀면 터질 것 같았다.

     

    두 가지 경우를 나눠서 생각하는 것이 포인트이다.

    1) 파티(x) -> 집

    2 ) 집 -> 파티(X)

     

     

    파티(X)에서 집으로 가는 경우는 단순하지만, 집에서 파티로 가는 경우를 체크하려면 모든 노드들을 다 한 번씩 체크해야한다. 그래서 역방향으로 가는 list(rlist) 를 하나 새로 만들어주고 X -> 다른 노드들을 체크해주면 된다.

    'ALGORITHM > BOJ' 카테고리의 다른 글

    [백준] 5676 음주 코딩  (0) 2021.02.07
    [백준] 14425 문자열 집합  (0) 2021.02.02
    [백준] 1854 K번째 최단경로 찾기  (0) 2021.01.31
    [백준] 1010 다리 놓기  (0) 2021.01.27
    [백준] 1766 문제집  (0) 2021.01.27

    댓글

Programming Diary