반응형
https://www.acmicpc.net/problem/5719
다잌스트라를 알고있다면 어려운 문제는 아니다. 경로추적과 경로가 여러가지일때 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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
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
|
반응형