본문 바로가기

ProgramSoliving

백준 : 5719

반응형

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

 

5719번: 거의 최단 경로

문제 요즘 많은 자동차에서는 GPS 네비게이션 장비가 설치되어 있다. 네비게이션은 사용자가 입력한 출발점과 도착점 사이의 최단 경로를 검색해 준다. 하지만, 교통 상황을 고려하지 않고 최단 경로를 검색하는 경우에는 극심한 교통 정체를 경험할 수 있다. 상근이는 오직 자기 자신만 사용 가능한 네비게이션을 만들고 있다. 이 네비게이션은 절대로 최단 경로를 찾아주지 않는다. 항상 거의 최단 경로를 찾아준다. 거의 최단 경로란 최단 경로에 포함되지 않는 도로로만

www.acmicpc.net

다잌스트라를 알고있다면 어려운 문제는 아니다. 경로추적과 경로가 여러가지일때 list에 중복적으로 쌓는 스킬이 필요하다. 그리고 경로를 데추적하면서 단방향 그래프를 삭제하면된다. 아직까지 자바가 익숙하지않아서
for을 통해 삭제하고싶은 값을 찾고 있으면 삭제하고 break하는 방법을 사용했다. 

나중에 한번 ArrayList를 remove를 인덱스형말고 오브젝트형으로 삭제하면 편할것같은데 그거에대한 연습을 해야겠다. Object형을 삭제할때는 주소값이 필요한데 경로에서 어떻게 받을지도 문제 인것같다.
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
 
public class B5719 {
    static int N,M;
    static int S,D;
    static int digit[];
    static ArrayList<Integer>[] route;
    static class VERTEX implements Comparable<VERTEX>{
        int u;
        int p;
        public VERTEX(int u, int p) {
            super();
            this.u = u;
            this.p = p;
        }
        @Override
        public int compareTo(VERTEX o) {
            if(this.p >o.p) {
                return 1;
            }
            return -1;
        }
    }
    
    static ArrayList<VERTEX>[] ver;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        while(true) {
            st = new StringTokenizer(br.readLine());
            N = Integer.parseInt(st.nextToken());
            M = Integer.parseInt(st.nextToken());
            if(N==0 && M==0)break;
            
            st = new StringTokenizer(br.readLine());
            S = Integer.parseInt(st.nextToken());
            D = Integer.parseInt(st.nextToken());
        
            ver = new ArrayList[N];
            for(int n=0;n<N;n++) {
                ver[n] = new ArrayList<VERTEX>();
            }
            
            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 p = Integer.parseInt(st.nextToken());
                ver[u].add(new VERTEX(v, p));
            }
            
            route = new ArrayList[N];
            
            //경로수 저장할거임
            for(int n=0;n<N;n++) {
                route[n] = new ArrayList<Integer>();
            }
            
            digit = new int[N];
            Arrays.fill(digit, 987654321);
            
            digit[S] = 0;
            PriorityQueue<VERTEX> q = new PriorityQueue<VERTEX>();
            q.add(new VERTEX(S, 0));
            
            while(!q.isEmpty()) {
                VERTEX tmp = q.poll();
                
                int size = ver[tmp.u].size();
                
                for(int s=0;s<size;s++) {
                    VERTEX next = ver[tmp.u].get(s);
                    
                    if(digit[next.u] > digit[tmp.u] + next.p) {
                        digit[next.u] = digit[tmp.u] + next.p;
                        route[next.u].clear();
                        route[next.u].add(tmp.u);
                        q.add(new VERTEX(next.u, digit[tmp.u] + next.p));
                    }else if(digit[next.u] == digit[tmp.u] + next.p) {
                        route[next.u].add(tmp.u);
                    }
                }
                
            }
            
 
            //다잌스트라 최단 경로를 구했다. 이제 경로를 백트래킹하면서 ver을 끊어준다.
            backT(D);
            
            //다시 다잌스트라를 구한다.
            digit = new int[N];
            Arrays.fill(digit, 987654321);
            
            digit[S] = 0;
            q = new PriorityQueue<VERTEX>();
            q.add(new VERTEX(S, 0));
            
            while(!q.isEmpty()) {
                VERTEX tmp = q.poll();
                
                int size = ver[tmp.u].size();
                
                for(int s=0;s<size;s++) {
                    VERTEX next = ver[tmp.u].get(s);
                    
                    if(digit[next.u] > digit[tmp.u] + next.p) {
                        digit[next.u] = digit[tmp.u] + next.p;
                        q.add(new VERTEX(next.u, digit[tmp.u] + next.p));
                    }
                }
                
            }
            if(digit[D]== 987654321) {
                System.out.println(-1);
            }else {
                System.out.println(digit[D]);
            }
        }
        
        
    }
 
    public static void backT(int cur) {
 
        int size = route[cur].size();
        if(size ==0) {
            return;
        }
        for(int s=0;s<size;s++) {
            int next = route[cur].get(s);
            for(int i=0;i<ver[next].size();i++) {
                if(ver[next].get(i).u == cur){
                    ver[next].remove(i);
                    break;
                }
            }
            
            backT(next);
        }
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
반응형

'ProgramSoliving' 카테고리의 다른 글

백준 : 2617  (0) 2020.02.26
백준 : 2251  (0) 2020.02.25
백준 : 1967  (0) 2020.02.24
백준 : 2250  (0) 2020.02.24
백준 : 9019  (0) 2020.02.23