본문 바로가기

ProgramSoliving

백준 : 1916

반응형

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

 

1916번: 최소비용 구하기

첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)이 주어지고 둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 주어진다. 그리고 그 다음에는 도착지의 도시 번호가 주어지고 또 그 버스 비용이 주어진다. 버스 비용은 0보다 크거나 같고, 100,000보다 작은 정수이다. 그리고 M+3째 줄에는 우리가 구하고자 하는 구간

www.acmicpc.net

 

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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 
 
public class B1916 {
    static int N;
    static int M;
 
    public static class Bus implements Comparable<Bus>{
        int v;
        int w;
 
        public Bus(int v, int w) {
            super();
 
            this.v = v;
            this.w = w;
        }
        public Bus(int v) {
            this.v = v;
        }
        @Override
        public int compareTo(Bus o) {
            if(this.w>o.w) {
                return 1;
            }
            else {
                return-1;
            }
        }
 
    }
 
    static ArrayList<Bus> list[];
 
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        
        N = Integer.parseInt(br.readLine());
        M = Integer.parseInt(br.readLine());
        
        list = new ArrayList[N+1];
        for(int n=1;n<=N;n++) {
            list[n] = new ArrayList<Bus>();
        }
        
        
        for(int m=0;m<M;m++) {
            st = new StringTokenizer(br.readLine());
            int u = Integer.parseInt(st.nextToken());
            int v = Integer.parseInt(st.nextToken());
            int w = Integer.parseInt(st.nextToken());
            list[u].add(new Bus(v,w));
        }
        
        // 출발지 도착지
        st = new StringTokenizer(br.readLine());
        int u = Integer.parseInt(st.nextToken());
        int v = Integer.parseInt(st.nextToken());
        
        System.out.println(Dijckstra(u, v));
        
    }
 
    public static int Dijckstra(int u, int v) {
        int digit[] = new int[N + 1];
        boolean check[] = new boolean[N + 1];
 
 
        PriorityQueue<Bus> q = new PriorityQueue<>();
        // 시작점은 비용이 없다 ㅎㅎㅎ
        digit[u] = 0;
        q.add(new Bus(u));
 
        while (!q.isEmpty()) {
            Bus b = q.poll();
 
            // 방문한 노드는 스킵한다.
            if (check[b.v])
                continue;
            check[b.v] = true;
            int len = list[b.v].size();
            
            for (int i = 0; i < len; i++) {
 
                if (digit[list[b.v].get(i).v] > digit[b.v] + list[b.v].get(i).w) {
                    digit[list[b.v].get(i).v] =  digit[b.v] + list[b.v].get(i).w;
                    q.add(new Bus(list[b.v].get(i).v,digit[b.v] + list[b.v].get(i).w));
                }
    
                
            }
 
        }
 
        return digit[v];
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

 

다잌스트라 연습

1. 시작노드 u 도착노드 v 라고할 대

digit 을 INF 값으로 초기화 한다.

시작노드의 digit[u] = 0 으로 초기화하고 우선순위큐에 넣는다.

 

이때 우선순위 큐의 정렬순서를 digit값으로 한다면 항상 digit값이 최소인것을 먼저 가져올 수가 있다.

항상 최소인 비용의 노드에서 탐색하는 것이 가장 적은 비용을 얻을 수 있다.

 

또한 현재노드에서 다른노드에 digit값을 바꿧을대 그노드를 Q에 추가한다.

 

방문한 노드는 탐색하지 않는다 되어있지만 사실상 저소스는 없어도 우선순위 큐에서 정리된다.

 

만약 우선순위 큐가아니라 일반 큐를 사용하고 check를 사용한다면 당연히 에러가난다.

 

이때는 일반큐에서는 check를 사용하지않고 q가 사라질때까지 사용한다.

 

우선순위 큐를 쓰면 항상 최적의 값으로한다.

 

 

 

 

 

반응형

'ProgramSoliving' 카테고리의 다른 글

백준 : 1238  (0) 2020.02.08
백준 : 17136  (0) 2020.02.07
백준 : 17142  (0) 2020.02.03
백준 : 17143  (0) 2020.02.03
백준 : 17822 JAVA  (0) 2020.02.02