Skip to content

Commit 84cc619

Browse files
committed
[Graph] baekjoon-5719
1 parent b41a8b7 commit 84cc619

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
| 05 | | [Baekjoon-11404 플로이드](./src/Graph/P11404) | Floyd-Warshall |
194194
| 06 | | [Baekjoon-1854 K번째 최단경로 찾기](./src/Graph/P1854) | Dijkstra |
195195
| 07 | | [Baekjoon-3860 할로윈 묘지](./src/Graph/P3860) | Bellman-Ford |
196+
| 06 | ⭐️ | [Baekjoon-5719 거의 최단 경로](./src/Graph/P5719) | Dijkstra |
196197

197198
### Union-Find
198199

src/Graph/P5719/Main.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package Graph.P5719;
2+
3+
import java.io.*;
4+
import java.util.*;
5+
6+
public class Main {
7+
8+
static int N, M, S, D, U, V, P;
9+
static ArrayList<Node>[] graph, reverse;
10+
static int[] dist;
11+
12+
public static void main(String[] args) throws Exception {
13+
System.setIn(new FileInputStream("src/Graph/P5719/input.txt"));
14+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
15+
StringTokenizer st = new StringTokenizer(br.readLine());
16+
17+
while ((N = stoi(st.nextToken())) != 0 && (M = stoi(st.nextToken())) != 0) {
18+
st = new StringTokenizer(br.readLine());
19+
S = stoi(st.nextToken()); D = stoi(st.nextToken());
20+
21+
graph = new ArrayList[N];
22+
reverse = new ArrayList[N];
23+
for (int i = 0; i < N; i++) {
24+
graph[i] = new ArrayList<>();
25+
reverse[i] = new ArrayList<>();
26+
}
27+
28+
while (M-- > 0) {
29+
st = new StringTokenizer(br.readLine());
30+
U = stoi(st.nextToken()); V = stoi(st.nextToken()); P = stoi(st.nextToken());
31+
graph[U].add(new Node(V, P));
32+
reverse[V].add(new Node(U, P));
33+
}
34+
35+
dijkstra();
36+
delPath();
37+
dijkstra();
38+
System.out.println(dist[D]);
39+
40+
st = new StringTokenizer(br.readLine());
41+
}
42+
}
43+
44+
static void dijkstra() {
45+
dist = new int[N];
46+
Arrays.fill(dist, -1);
47+
48+
PriorityQueue<Node> pq = new PriorityQueue<>(((o1, o2) -> o1.dist - o2.dist));
49+
pq.offer(new Node(S, 0));
50+
while (!pq.isEmpty()) {
51+
Node cur = pq.poll();
52+
if (dist[cur.idx] != -1) continue;
53+
54+
dist[cur.idx] = cur.dist;
55+
for (Node next : graph[cur.idx]) {
56+
if (dist[next.idx] == -1)
57+
pq.offer(new Node(next.idx, dist[cur.idx] + next.dist));
58+
}
59+
}
60+
}
61+
62+
static void delPath() {
63+
Queue<Integer> q = new LinkedList<>();
64+
boolean[] visited = new boolean[N];
65+
q.offer(D); visited[D] = true;
66+
while (!q.isEmpty()) {
67+
int cur = q.poll();
68+
for (Node prev : reverse[cur]) {
69+
if (dist[prev.idx] + prev.dist == dist[cur]) {
70+
graph[prev.idx].remove(new Node(cur, prev.dist));
71+
if (!visited[prev.idx]) {
72+
visited[prev.idx] = true;
73+
q.offer(prev.idx);
74+
}
75+
}
76+
}
77+
}
78+
}
79+
80+
static int stoi(String s) { return Integer.parseInt(s); }
81+
82+
static class Node {
83+
int idx, dist;
84+
85+
public Node(int idx, int dist) {
86+
this.idx = idx;
87+
this.dist = dist;
88+
}
89+
90+
@Override
91+
public boolean equals(Object o) {
92+
Node node = (Node) o;
93+
return idx == node.idx && dist == node.dist;
94+
}
95+
}
96+
}

src/Graph/P5719/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## [baekjoon-5719] 거의 최단 경로
2+
3+
![image](https://user-images.githubusercontent.com/22045163/107655671-00a46e80-6cc7-11eb-83e9-e2834b9a87be.png)
4+
![image](https://user-images.githubusercontent.com/22045163/107656046-19ad1f80-6cc7-11eb-80db-179aaa45aefc.png)
5+
6+
### 풀이 과정
7+
8+
다익스트라 응용 문제이다. 많이 어려웠다. ㅠㅠ
9+
10+
처음에는 [K번째 최단경로 찾기](../P1854) 문제와 같은 방식으로 2번째 최단 경로를 찾으면 되는줄 알았으나, 이 문제는 그렇게 푸는 것이 아니라
11+
**최적의 최단 경로를 찾은 후 그 최단 경로를 지우고, 다시 최단 경로를 찾아야** 올바른 정답을 도출할 수 있었다.
12+
즉 다익스트라 -> 최단 경로 지우기 -> 다익스트라 순서로 풀이해야 하는 것이다.
13+
14+
최단 경로를 지우는 방법은 마지막 노드에서 역순으로 거쳐온 노드를 찾아 해당 정보를 지우면 되고, bfs를 통해 해결할 수 있다.
15+
이 때 방문했던 노드에 대해서는 방문 처리를 해주어야 bfs 메모리 초과 이슈를 피할 수 있다.
16+
17+
![image](https://user-images.githubusercontent.com/22045163/107656230-4bbe8180-6cc7-11eb-910a-74af12747b03.png)
18+
19+
![image](https://user-images.githubusercontent.com/22045163/107656082-23cf1e00-6cc7-11eb-84fd-3cf205abc5a8.png)

src/Graph/P5719/input.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
7 9
2+
0 6
3+
0 1 1
4+
0 2 1
5+
0 3 2
6+
0 4 3
7+
1 5 2
8+
2 6 4
9+
3 6 2
10+
4 6 4
11+
5 6 1
12+
4 6
13+
0 2
14+
0 1 1
15+
1 2 1
16+
1 3 1
17+
3 2 1
18+
2 0 3
19+
3 0 2
20+
6 8
21+
0 1
22+
0 1 1
23+
0 2 2
24+
0 3 3
25+
2 5 3
26+
3 4 2
27+
4 1 1
28+
5 1 1
29+
3 0 1
30+
0 0

0 commit comments

Comments
 (0)