반응형
https://www.acmicpc.net/problem/1504
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
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];
}
}
반응형
'알고리즘 > [ 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 |