1. ๋ฌธ์ ์ค๋ช ๐
์งํ
๊ณผ ์ฑํ
์ ์๋ก์ด ์ฝ์ ์ฅ์๋ฅผ ์ฐพ์์ฃผ๋ ๋ฌธ์ ๋ก์, ๋ค์ต์คํธ๋ผ๋ฅผ ํตํด ๊ฐ์์ ์ถ๋ฐ์ ์์ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต์ ๋๋ฌ ๋น์ฉ์ ๊ตฌํ๊ณ , ์ด๋ฅผ ํตํด 4๊ฐ์ง ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฝ์ ์ฅ์
๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
ํ์ง๋ง, ์ถ์ ์๊ฐ ์ง๋ฌธ์ ๋๊ฒ ๋ชจํธํ๊ฒ ์ ์ด์, ์กฐ๊ฑด์ ์ง์๊ฐ ํท๊ฐ๋ฆฐ๋ค.
์ฝ์ ์ฅ์
์ ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
- 1๏ธโฃ ๊ฐ์์ ์ถ๋ฐ์ ์ ์ฝ์ ์ฅ์๊ฐ ๋ ์ ์๋ค.
- 2๏ธโฃ ๋ ๋ค ์ต์ ๋น์ฉ์ผ๋ก ๋ฟ์ ์ ์๋ ์ฅ์์ฌ์ผ ํ๋ค.
- 3๏ธโฃ ์งํ์ด๊ฐ ์ฑํ๋ณด๋ค ๋จผ์ ๋์ฐฉํ๋ ์ฅ์์ฌ์ผ ํ๋ค.
- 4๏ธโฃ ์์ ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ๋ ์ฅ์๊ฐ ๋ณต์๋ผ๋ฉด, ๊ทธ ์ค ์งํ์ด๊ฐ ๋นจ๋ฆฌ ๋์ฐฉํ๋ ์ฅ์๋ฅผ ๊ณ ๋ฅธ๋ค. (์ด ๋ง์ ๋ ๋ณต์์ด๋ฉด, ์ ์ ๋ฒํธ๊ฐ ๋น ๋ฅธ ๊ฒ์ ๊ณ ๋ฅธ๋ค.)
์ด ์กฐ๊ฑด์ ๋ณด๋ฉด,
๊ฐ์์ ์ถ๋ฐ์ ์ด ์๋๋ฉด์, ์งํ์ด๊ฐ ์ฑํ๋ณด๋ค ๋จผ์ ๋์ฐฉํ๋ฉด์, ์งํ์ด๊ฐ ๊ฐ๋ฅํ ๋น ๋ฅด๊ฒ ๋์ฐฉํ๋ ์ฅ์ ๋ผ๋ ์๋ฏธ๋ก ๋ฐ์๋ค์ผ ์ ์๋ค. (์ฆ, ๋ชจ๋๊ฐ AND
๋ก ์ญ์ฌ์๋ค๊ณ ์๊ฐํด์, ์กฐ๊ฑด์ ์์๋ฅผ ๋ฌด์ํด๋ ๋๋ค๊ณ ์๊ฐํ๋ค๋ ๊ฒ์ด๋ค.)
๋ค๋ฅธ ๋ฌธ์ ์๋ค๋ฉด, ์ด๋ฌํ ๋ฐ์์ ๋ง์ผ๋, ์ด ๋ฌธ์ ๋ ๊ทธ๋ ๊ฒ ์กฐ๊ฑด์ ์์๋ฅผ ๋ฌด์ํ๋ฉด ํ๋ฆฐ๋ค. ๊ทผ๋ฐ ์ด๋, ํ์ด์์ ํด์ ์ฐฉ์ค๊ฐ ์๋๋ผ, ์ถ์ ์๊ฐ ๋ฌธ์ ๋ฅผ ๋ชจํธํ๊ฒ ๊ธฐ์ ํ ํ์ด๋ผ ์๊ฐํ๋ค. ์ฌํผ ๋ฌธ์ ๋ฅผ ํ๋ ค๋ฉด, ์กฐ๊ฑด์ ์์๋๋ก ๋ง์กฑ์ํค๋ ์ ์ ์ ์ฐพ์์ผ ํ๋ค. ์ฆ
- 1๏ธโฃ ์์ ์ ์ , ๋์ฐฉ ์ ์ ์ ์ธ
- 2๏ธโฃ ๋ชจ๋ ์ ์ ์ค ๋์ ์ด๋ ๋น์ฉ์ ํฉ์ณค์ ๋, ์ต์ ๋น์ฉ์ด ๋๋ ์ ์ ๋ง๊ณ ๋ชจ๋ ์ ์ธ
- 3๏ธโฃ ๊ทธ ์ค ์งํ์ด๊ฐ ์ฑํ๋ณด๋ค ๋ฆ๊ฒ ๋์ฐฉํ๋ ์ ์ ์ ์ธ
- 4๏ธโฃ ๊ทธ ์ค ์งํ์ด๊ฐ ์ ์ผ ๋นจ๋ฆฌ ๋์ฐฉํ๋ ์ ์ ๊ณ ๋ฅด๊ธฐ (์์ผ๋ฉด ์ ์ ๋ฒํธ ๋น ๋ฅธ ์)
2. ๊ตฌํ ๋ฐฉ๋ฒ ๐๏ธ
KEY WORD
: DIJKSTRA
- 1๏ธโฃ ์ธ์ ๋ฆฌ์คํธ๋ก ๊ทธ๋ํ ๊ตฌํ ๋ฐ, ๊ฐ์์ ๊ฑฐ๋ฆฌ๋ฐฐ์ด ์์ฑ
- 2๏ธโฃ ๊ฐ์์ ์ถ๋ฐ์ ์์
๋ค์ต์คํธ๋ผ
๋๋ ค์ ๊ฑฐ๋ฆฌ ๋ฐฐ์ด ์์ฑ - 3๏ธโฃ 4๊ฐ์ง ์กฐ๊ฑด์ ์ฐจ๋ก๋๋ก ํ์ธํ๋ฉฐ, ์กฐ๊ฑด์ ๋ถํฉํ์ง ์๋ ์ ์ ์ ๊ฑฐํด๋๊ฐ๊ธฐ
- 4๏ธโฃ 4๋ฒ์กฐ๊ฑด๊น์ง ํ๊ณ ๋จ์ ๊ฒ๋ค ์ค ์งํ์ด๊ฐ ๊ฐ์ฅ ๋นจ๋ฆฌ ๋์ฐฉํ๋ ๊ฒ, ๊ทธ ์ค์์๋ ์ ์ ๋ฒํธ๊ฐ ๋น ๋ฅธ ๊ฒ์ ์ถ๋ ฅ
(1) ์๊ฐ๋ณต์ก๋ ๋ถ์ ๐
๋ค์ต์คํธ๋ผ๋ฅผ ์ฐ์ ์์ ํ๋ก ๊ตฌํํ๊ธฐ ๋๋ฌธ์, ์ ์ ์ ์๋ฅผ V
, ๊ฐ์ ์ ์๋ฅผ M
์ด๋ผ๊ณ ํ ๋,
$O(V \log M)$
3. ์ฝ๋ ์๊ฐ ๐
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static int V, M, J, S;
static long min_dist, J_smallest_dis, ans;
static long [] distJ, distS; // ์งํ์ด ์ต๋จ๊ฑฐ๋ฆฌ, ์ฑํ ์ต๋จ๊ฑฐ๋ฆฌ
static ArrayList<Node>[] lists;
static ArrayDeque<Node> land_of_promise = new ArrayDeque<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
V = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
lists = new ArrayList[V + 1];
distJ = new long [V + 1];
distS = new long [V + 1];
Arrays.fill(distJ, Integer.MAX_VALUE);
Arrays.fill(distS, Integer.MAX_VALUE);
for (int i = 1; i < V + 1; i++) {
lists[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int weight = Integer.parseInt(st.nextToken());
lists[start].add(new Node(end, weight));
lists[end].add(new Node(start, weight));
}
st = new StringTokenizer(br.readLine());
J = Integer.parseInt(st.nextToken());
S = Integer.parseInt(st.nextToken());
dijkstar(true);
dijkstar(false);
// System.out.println("์งํ: " + Arrays.toString(distJ));
// System.out.println("์ฑํ: " + Arrays.toString(distS));
min_dist = Integer.MAX_VALUE;
for (int i = 0; i < V + 1; i++) {
if( i == J || i == S) continue;
min_dist = (int)Math.min(min_dist, distJ[i] + distS[i]);
}
ans = -1;
J_smallest_dis = Integer.MAX_VALUE;
for (int i = V ; i >= 1; i --) {
if( i == J || i == S) continue;
if(min_dist != distJ[i] + distS[i]) continue;
if(distJ[i] > distS[i]) continue;
if(J_smallest_dis >= distJ[i]) {
J_smallest_dis = distJ[i];
ans = i;
}
}
System.out.println(ans);
}
public static void dijkstar (boolean isJ) {
int START = isJ? J : S;
long [] dist = isJ? distJ : distS;
PriorityQueue<Dist> pq = new PriorityQueue<>(Comparator.comparingLong(o -> o.dist));
dist[START] = 0;
pq.add(new Dist(START, 0));
while(!pq.isEmpty()) {
Dist now = pq.poll();
if(now.dist != dist[now.idx]) continue;
for (int i = 0; i < lists[now.idx].size(); i++) {
Node next = lists[now.idx].get(i);
if(dist[next.idx] > dist[now.idx] + next.w){
dist[next.idx] = dist[now.idx] + next.w;
pq.add(new Dist(next.idx, dist[next.idx]));
}
}
}
}
}
class Node {
int idx;
int w;
public Node (int idx, int w){
this.idx = idx;
this.w = w;
}
}
class Dist {
int idx;
long dist;
public Dist(int idx, long dist){
this.idx= idx;
this.dist = dist;
}
}
(1) ์ ์ ๋ํ๋ด๋ ํด๋์ค 2๊ฐ ์
Dist ํด๋์ค๋ ๋ค์ต์คํธ๋ผ์์ <๋์ฐฉ์ ์ , ์์์ ์์ ๋์ฐฉ ์ ์ ๊น์ง ์ต์ ๋น์ฉ>
์ ๋ํ๋ด๊ธฐ ์ํด ์ฌ์ฉํ๊ณ , Node๋ ์ธ์ ๋ฆฌ์คํธ์์ <๋์ฐฉ ์ ์ , ๊ฐ์ค์น>
๋ฅผ ๋ํ๋ด๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ๋์ ๊ฒน์ณ ์จ๋ ๋๋, ์ฝ๋ ์์ฑ ์ค ํท๊ฐ๋ฆด ๋ฏ ์ถ์ด ๋๋์๋ค.
(2) ๋ง์ง๋ง์ ๊ฑฐ๋ฆฌ ๋ฐฐ์ด์ ๋ค์์๋ถํฐ ๊ณ์ฐ
for (int i = V ; i >= 1; i --) {
if( i == J || i == S) continue;
if(min_dist != distJ[i] + distS[i]) continue;
if(distJ[i] > distS[i]) continue;
if(J_smallest_dis >= distJ[i]) {
J_smallest_dis = distJ[i];
ans = i;
}
}
J_smallest_dis
๋ ์งํ์ด๊ฐ ๊ฐ์ฅ ๋นจ๋ฆฌ ๋์ฐฉํ๋ ์ ์ ๊น์ง์ ๋น์ฉ์ ๋ํ๋ธ๋ค. ์ ๋น๊ต๋ฅผ ๋ณด๋ฉด, ํ์ฌ ๋ณด๊ณ ์๋ ์ ์ ๊น์ง ์งํ์ด๊ฐ ๊ฐ๋ ๋น์ฉ๊ณผ J_smallest_dis
๊ฐ ๊ฐ์๋ ๊ฐฑ์ ํ๋ค. ์ด๋ ์กฐํ๋ฅผ ์ญ์์ผ๋ก ํ๊ธฐ ๋๋ฌธ์ ์์ฐ์ค๋ฝ๊ฒ, ๋น์ฉ์ด ๊ฐ๋ค๋ฉด ๋ ์์ idx๊ฐ ๋ต์ด ๋๋๋ก ๋ง๋ ๊ฒ์ด๋ค.
4. ๋ฐฐ์ด ๊ฒ๋ค ๐ฏ
๋๋ฌด ์ ํ๋ ค์, ์กฐ๊ฑด ๋ถ๋ถ์ ๋ค๋ฅธ ์ฌ๋์ ํ์ด๋ฅผ ์ฐธ๊ณ ํ๋ค. ๋ด ์ฝ๋์์๋ 4 ~ 50 ์ค ๋๋ ์ฝ๋๋ฅผ ๋จ์ํ, 3์ค์ continue
๋ก ์ฒ๋ฆฌํ ๊ฒ์ ๋ณด๊ณ , ๋๋ ์ฝ๊ฒ ์๊ฐํ๋ฉฐ ๋ฌธ์ ๋ฅผ ํ์ด์ผ ๊ฒ ๋ค๊ณ ์๊ฐํ๋ค.