문제풀이/백준
[백준]17396: 백도어 - JAVA
빈둥벤둥
2021. 7. 25. 22:46
[백준]17396: 백도어

17396번: 백도어
첫 번째 줄에 분기점의 수와 분기점들을 잇는 길의 수를 의미하는 두 자연수 N과 M이 공백으로 구분되어 주어진다.(1 ≤ N ≤ 100,000, 1 ≤ M ≤ 300,000) 두 번째 줄에 각 분기점이 적의 시야에 보이는
www.acmicpc.net
풀이
🪑 문제가 좀 복잡해 보여서 그렇지 사실 문제에 필요 없는 정보를 제외하면 그냥 최단거리 문제이당.
📝 문제를 푸는데 필요한 조건만 정리해 보자.
- 0에서 N-1번째 분기점 까지 가는 최단 거리를 구해준다.
- 이때 시야 정보도 주어지는데 0이면 해당 분기점일 때 상대 시야에서 보이지 않는다는 의미이고, 1이면 상대 시야에서 보인다는 의미이다.
- 시야에서 보이지 않으면서 N-1번째 분기점으로 갈 수 있는 최단거리를 구하면 된다.
🔧 문제를 풀어보자.
- 각 분기점 사이의 정보를 입력 받는다.
- 다익스트라 알고리즘을 사용하여 최단거리를 구한다.
- 출력한다.
🔹 각 분기점 사이의 정보를 입력 받는다.
- 분기점 간에 이동할 수 있는 간선의 정보가 주어지며 이때 간선은 양방향으로 이동이 가능하다.
🔹 다익스트라 알고리즘을 사용하여 최단거리를 구한다.
- 0번 분기점에서 N-1번 분기점으로 이동하는 최단 거리를 구하는 문제이므로 최단 거리 알고리즘 중에서 다익스트라를 사용한다.
- 다익스트라 탐색시 유의할 점 하나가 있다면 시야에 들어오는 분기점으로는 가지 못하며, 마지막 분기점은 항상 시야에 들어온다는 점이다.
- 경로를 저장하는 배열은 long타입으로 선언해 주었다. (int로 하니 틀렸어서 long으로 고치니 되었다.)
🔹 경로가 존재하는지 여부를 확인하여 최단 경로를 출력해 준다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
import java.util.*;
public class Main {
static int n, m;
static boolean[] sight;
static ArrayList<Node>[] list;
static long[] dist;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//입력
n = scan.nextInt();
m = scan.nextInt();
sight = new boolean[n];
for(int i = 0; i < n; i++) {
int flag = scan.nextInt();
if(flag == 1) sight[i] = true;
else sight[i] = false;
}
list = new ArrayList[n];
for(int i = 0; i < n; i++) {
list[i] = new ArrayList<>();
}
for(int i = 0; i < m; i++) {
int s = scan.nextInt();
int e = scan.nextInt();
int c = scan.nextInt();
list[s].add(new Node(e, c));
list[e].add(new Node(s, c));
}
//입력 끝
dist = new long[n];
Arrays.fill(dist, Long.MAX_VALUE);
dist[0] = 0;
dijkstra();
if(dist[n - 1] == Long.MAX_VALUE) System.out.println("-1");
else System.out.println(dist[n - 1]);
}
public static void dijkstra() {
PriorityQueue<Node> q = new PriorityQueue<>();
boolean[] visited = new boolean[n];
q.offer(new Node(0, 0));
while(!q.isEmpty()) {
Node current = q.poll();
if(visited[current.node]) continue;
visited[current.node] = true;
for(int i = 0; i < list[current.node].size(); i++) {
Node next = list[current.node].get(i);
if(next.node != n - 1 && sight[next.node]) continue;
if(dist[next.node] > dist[current.node] + next.cost) {
dist[next.node] = dist[current.node] + next.cost;
q.offer(new Node(next.node, dist[next.node]));
}
}
}
}
public static class Node implements Comparable<Node> {
int node;
long cost;
public Node(int node, long cost) {
this.node = node;
this.cost = cost;
}
@Override
public int compareTo(Node n) {
if(this.cost - n.cost > 0) return 1;
else return -1;
}
}
}
|
cs |