알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][1504] 특정한 최단경로

kim.svadoz 2021. 11. 2. 16:28
728x90
반응형

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

 

1504번: 특정한 최단 경로

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 256 MB 38669 9716 6517 24.812%

문제

방향성이 없는 그래프가 주어진다. 세준이는 1번 정점에서 N번 정점으로 최단 거리로 이동하려고 한다. 또한 세준이는 두 가지 조건을 만족하면서 이동하는 특정한 최단 경로를 구하고 싶은데, 그것은 바로 임의로 주어진 두 정점은 반드시 통과해야 한다는 것이다.

세준이는 한번 이동했던 정점은 물론, 한번 이동했던 간선도 다시 이동할 수 있다. 하지만 반드시 최단 경로로 이동해야 한다는 사실에 주의하라. 1번 정점에서 N번 정점으로 이동할 때, 주어진 두 정점을 반드시 거치면서 최단 경로로 이동하는 프로그램을 작성하시오.

입력

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존재하며, 그 거리가 c라는 뜻이다. (1 ≤ c ≤ 1,000) 다음 줄에는 반드시 거쳐야 하는 두 개의 서로 다른 정점 번호 v1과 v2가 주어진다. (v1 ≠ v2, v1 ≠ N, v2 ≠ 1)

출력

첫째 줄에 두 개의 정점을 지나는 최단 경로의 길이를 출력한다. 그러한 경로가 없을 때에는 -1을 출력한다.

예제 입력 1

4 6
1 2 3
2 3 3
3 4 1
1 3 5
2 4 5
1 4 4
2 3

예제 출력 1

7

접근

처음에 최단거리 키워드를 보고 나도 모르게 MST로 접근했고 안된다는 것을 파악 후 Dijkstra로 변경.

그러나 특정 정점을 건너기 위한 해법이 생각나지 않아 다른분들의 풀이를 참고해 풀이했다.

코드

/**
 * BOJ 1504 특정한 최단경로
 * 다익스트라
 */
import java.io.*;
import java.util.*;

public class p1504 {
    static class Node implements Comparable<Node> {
        int v, cost;

        public Node(int v, int cost) {
            this.v = v;
            this.cost = cost;
        }
        public int compareTo(Node o) {
            return cost - o.cost;
        }
    }
    static final int INF = Integer.MAX_VALUE;
    static int n, e;
    static int[] dp;
    static boolean[] visited;
    static List<List<Node>> list;
    static PriorityQueue<Node> pq;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        e = Integer.parseInt(st.nextToken());

        dp = new int[n + 1];
        visited = new boolean[n + 1];
        list = new ArrayList<>();
        pq = new PriorityQueue<>();

        for (int i = 0; i <= n; i++) {
            list.add(new ArrayList<>());
        }
        while (e-- > 0) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());

            list.get(a).add(new Node(b, c));
            list.get(b).add(new Node(a, c));
        }
        st = new StringTokenizer(br.readLine());
        int v1 = Integer.parseInt(st.nextToken());
        int v2 = Integer.parseInt(st.nextToken());

        long res1  = 0;
        res1 += dijkstra(1, v1);
        res1 += dijkstra(v1, v2);
        res1 += dijkstra(v2, n);

        long res2 = 0;
        res2 += dijkstra(1, v2);
        res2 += dijkstra(v2, v1);
        res2 += dijkstra(v1, n);

        long answer = Math.min(res1, res2);
        answer = answer >= INF ? -1 : answer;

        System.out.println(answer);
    }
    static int dijkstra(int s, int e) {
        Arrays.fill(dp, INF);
        Arrays.fill(visited, false);

        pq = new PriorityQueue<>();
        pq.add(new Node(s, 0));
        dp[s] = 0;

        while (!pq.isEmpty()) {
            Node cur = pq.poll();
            int v = cur.v;
            if (visited[v]) continue;
            visited[v] = true;
            if (v == e) break;

            for (Node next : list.get(v)) {
                if (visited[next.v]) continue;

                if (!visited[next.v] && dp[next.v] > dp[v] + next.cost) {
                    dp[next.v] = dp[v] + next.cost;
                    pq.add(new Node(next.v, dp[next.v]));
                }
            }
        }
        return dp[e];
    }
}
728x90
반응형

'알고리즘 > [ Baekjoon ]' 카테고리의 다른 글

[ BOJ ][JAVA][1477] 휴게소 세우기  (0) 2021.11.03
[ BOJ ][JAVA][3190] 뱀  (0) 2021.11.02
[ BOJ ][JAVA][1484] 다이어트  (0) 2021.11.02
[ BOJ ][JAVA][16953] A -> B  (0) 2021.11.02
[ BOJ ][JAVA][6159] 코스튬 파티  (0) 2021.11.01