티스토리 뷰
문제
어떤 나라에는 1번부터 N번까지의 도시와 M개의 단방향 도로가 존재한다. 모든 도로의 거리는 1이다.
이 때 특정한 도시 X로부터 출발하여 도달할 수 있는 모든 도시 중에서, 최단 거리가 정확히 K인 모든 도시들의 번호를 출력하는 프로그램을 작성하시오. 또한 출발 도시 X에서 출발 도시 X로 가는 최단 거리는 항상 0이라고 가정한다.
예를 들어 N=4, K=2, X=1일 때 다음과 같이 그래프가 구성되어 있다고 가정하자.
이 때 1번 도시에서 출발하여 도달할 수 있는 도시 중에서, 최단 거리가 2인 도시는 4번 도시 뿐이다. 2번과 3번 도시의 경우, 최단 거리가 1이기 때문에 출력하지 않는다.
입력
첫째 줄에 도시의 개수 N, 도로의 개수 M, 거리 정보 K, 출발 도시의 번호 X가 주어진다. (2 ≤ N ≤ 300,000, 1 ≤ M ≤ 1,000,000, 1 ≤ K ≤ 300,000, 1 ≤ X ≤ N) 둘째 줄부터 M개의 줄에 걸쳐서 두 개의 자연수 A, B가 공백을 기준으로 구분되어 주어진다. 이는 A번 도시에서 B번 도시로 이동하는 단방향 도로가 존재한다는 의미다. (1 ≤ A, B ≤ N) 단, A와 B는 서로 다른 자연수이다.
출력
X로부터 출발하여 도달할 수 있는 도시 중에서, 최단 거리가 K인 모든 도시의 번호를 한 줄에 하나씩 오름차순으로 출력한다.
이 때 도달할 수 있는 도시 중에서, 최단 거리가 K인 도시가 하나도 존재하지 않으면 -1을 출력한다.
import java.util.*;
import java.io.*;
public class Main {
static int N;
static List<Edge> map[];
static int[] distances; // 최단거리
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.valueOf(st.nextToken()); // 도시의 개수
int roadCount = Integer.valueOf(st.nextToken());
int findDistance = Integer.valueOf(st.nextToken());
int startCity = Integer.valueOf(st.nextToken());
map = new ArrayList[N + 1];
// 초기 거리는 무한대(INF)로 지정
distances = new int[N + 1];
Arrays.fill(distances, Integer.MAX_VALUE);
for (int i = 1; i <= N; i++) {
map[i] = new ArrayList<>();
}
for (int i = 0; i < roadCount; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.valueOf(st.nextToken());
int to = Integer.valueOf(st.nextToken());
map[from].add(new Edge(to, 1));
}
// 다익스트라 시작
dijkstra(startCity);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= N; i++) {
if (distances[i] != Integer.MAX_VALUE && distances[i] == findDistance) {
sb.append(i+"\\n");
}
}
System.out.println(sb.length() == 0 ? -1 : sb.toString().trim());
}
private static class Edge implements Comparable<Edge> {
private int from;
private int time;
Edge(int from, int time) {
this.from = from;
this.time = time;
}
// 최단 경로를 위해 compareTo를 오버라이드해준다.
@Override
public int compareTo(Edge o) {
return this.time - o.time;
}
}
private static void dijkstra(int infectiousComputer) {
PriorityQueue<Edge> queue = new PriorityQueue<>();
// 첫 정점의 거리는 0으로 설정
distances[infectiousComputer] = 0;
// 첫 정점과 0을 우선순위 큐에 넣어준다.
queue.add(new Edge(infectiousComputer, 0));
while (!queue.isEmpty()) {
Edge Edge = queue.poll();
int standardNode = Edge.from; // 기준 노드
int time = Edge.time; // 첫 정점에서 기준 노드와의 거리
if (distances[standardNode] < time) {
continue;
}
List<Edge> anotherEdges = map[standardNode]; // 기준 노드에 연결된 노드들의 리스트
for (Edge anotherEdge : anotherEdges) {
int nextFrom = anotherEdge.from; // 해당 노드
/**
* anotherEdge.time - 기준 노드 ~ 해당 노드 거리
* time : 첫 정점 노드 ~ 기준 노드
* 따라서, nextTime은 첫 정점 노드 ~ 기준 노드 ~ 해당 노드 거리
*/
int nextTime = anotherEdge.time + time;
// 첫 정점에서 해당 노드와의 거리(distances[nextFrom]과 nextTime을 비교 후 업데이트
if (distances[nextFrom] > nextTime) {
distances[nextFrom] = nextTime;
// 우선순위 큐에 넣어준다.
queue.add(new Edge(nextFrom, nextTime));
}
}
}
}
// private static void dfs(int V) {
//// for (int i = 1; i <= N; i++) {
//// if (visit[i]) continue;
//// if (map[V][i]) {
//// visit[i] = true;
//// dfs(i);
//// }
//// }
//// }
}
'알고리즘' 카테고리의 다른 글
BOJ1439 뒤집기 java (0) | 2022.01.30 |
---|---|
BOJ1753 최단경로 java - 다익스트라 (0) | 2022.01.29 |
최단 경로 문제 (다익스트라) (0) | 2022.01.29 |
BOJ10282 해킹 java (0) | 2022.01.28 |
BOJ1325 효율적인 해킹 java (0) | 2022.01.28 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- kotest
- Spring Boot
- 디자인패턴
- 테라폼
- Spring
- 백준
- MSA
- BOJ
- kkoon9
- Java
- Effective Java
- 알고리즘
- 디자인 패턴
- Algorithm
- JPA
- 프로그래머스
- 클린 아키텍처
- 코테
- Olympiad
- 정규표현식
- AWS
- 클린 코드
- 객체지향
- C++
- node.js
- Kotlin
- BAEKJOON
- 이팩티브 자바
- programmers
- 이펙티브 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함