(문제 : https://www.acmicpc.net/problem/11779)
답은 맞았지만 시간초과가 나는 상태였음. 재채점 후 그냥 틀린 문제는 많았지만 이런 경우는 처음이어서 해결방법을 찾을 수 없는 상태였다.
평범한 다익스트라 문제지만 틀린이유
먼저 해당 블로그를 참고하였음.(http://www.secmem.org/blog/2019/01/09/wrong-dijkstra/)
애초에 다익스트라를 잘못 구현할 경우 같은 vertex를 여러 번 방문하는 경우가 있다. 해결 방법은 vertex를 여러 번 방문하지 않도록 설정하는 것이다.
// 앞부분 생략
PriorityQueue<Node> q = new PriorityQueue<>();
q.add(new Node(S, 0));
d[S] = 0;
num[S] = 1;
str[S] = S + " ";
while(!q.isEmpty()) {
Node cur = q.poll();
int curNode = cur.end;
int curWeight = cur.weight;
visited[curNode] = true; // 이 부분에서 visited를 확인하지 않음.
for(int i = 0; i < list[curNode].size(); i++) {
int nextNode = list[curNode].get(i).end;
int nextWeight = list[curNode].get(i).weight;
if(!visited[nextNode] && d[nextNode] > curWeight + nextWeight) {
d[nextNode] = curWeight + nextWeight;
str[nextNode] = str[curNode] + nextNode + " ";
num[nextNode] = num[curNode] + 1;
q.add(new Node(nextNode, d[nextNode]));
}
}
}
// 뒷 부분 생략
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 Main {
public static class Node implements Comparable<Node> {
int end;
int weight;
Node (int end, int weight) {
this.end = end;
this.weight = weight;
}
public int compareTo(Node o) {
return this.weight - o.weight;
}
}
public static final int INF = 100_000 * 1000;
public static ArrayList<Node> list[];
public static boolean[] visited;
public static int[] d, num;
public static String[] str;
public static int N, M, S, E, W;
public static void main(String[] args) throws 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];
visited = new boolean[N + 1];
d = new int[N + 1];
num = new int[N + 1];
str = new String[N + 1];
Arrays.fill(d, INF);
for(int i = 0; i <= N; i++)
list[i] = new ArrayList<>();
while(M --> 0) {
st = new StringTokenizer(br.readLine());
S = Integer.parseInt(st.nextToken());
E = Integer.parseInt(st.nextToken());
W = Integer.parseInt(st.nextToken());
list[S].add(new Node(E, W));
}
st = new StringTokenizer(br.readLine());
S = Integer.parseInt(st.nextToken());
E = Integer.parseInt(st.nextToken());
PriorityQueue<Node> q = new PriorityQueue<>();
q.add(new Node(S, 0));
d[S] = 0;
num[S] = 1;
str[S] = S + " ";
while(!q.isEmpty()) {
Node cur = q.poll();
int curNode = cur.end;
int curWeight = cur.weight;
if(visited[curNode]) continue;
visited[curNode] = true;
for(int i = 0; i < list[curNode].size(); i++) {
int nextNode = list[curNode].get(i).end;
int nextWeight = list[curNode].get(i).weight;
if(!visited[nextNode] && d[nextNode] > curWeight + nextWeight) {
d[nextNode] = curWeight + nextWeight;
str[nextNode] = str[curNode] + nextNode + " ";
num[nextNode] = num[curNode] + 1;
q.add(new Node(nextNode, d[nextNode]));
}
}
}
System.out.println(d[E]);
System.out.println(num[E]);
System.out.println(str[E]);
}
}
예전에 풀었던 문제지만 다익스트라를 다시 한 번 정확하게 짚고 넘어가야겠다고 생각하게 된 문제이다.
이런걸 저격하는 사람은 대단한 사람인듯..(feat. djm03178)