Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Knapsack
- BeautifulSoup
- 피보나치 수
- SSAFY
- 비트마스크
- 완전 탐색
- 크루스칼
- 조합
- 빠른 입출력
- 스택
- MST
- lis
- BFS
- 순열
- DP
- 우선순위 큐
- 분할 정복
- 시뮬레이션
- dfs
- 이분 탐색
- 메모리풀
- 링크드리스트
- 문자열
- 세그먼트 트리
- 중복 순열
- 클래스
- 백트래킹
- 큐
- 그리디
- 재귀
Archives
- Today
- Total
작심 24/7
[백준] 1753번 최단경로 (C++, JAVA) 본문
1753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1≤V≤20,000, 1≤E≤300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1≤K≤V)가 주어진다.
www.acmicpc.net
graph[정점 A] = (정점 B, A→B 비용)
으로 값을 입력받은 후
dist[i] = K→i 비용
을 저장한다.
처음에는 모두 무한대로 저장해 두고
K→K일 때만 0을 저장해준다.
우선순위 큐 pq는
비용을 기준으로 오름차순 정렬된다.
제일 처음엔 시작점 K와 K→K 비용 0을 넣어준다.
pq의 top에 있는 정점을 mid라 표현할 때,
mid에서 바로 갈 수 있는 정점들 to를 탐색해주며
시작점 K→to 비용보다
시작점 K→mid 비용 + mid→to 비용이 더 작으면
dist[to]를 갱신해주고
pq에도 값을 넣어준다.
pq가 빌 때까지 이 과정을 반복하고
dist 값들을 출력시키면 된다.
< C++ 코드 >
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <queue>
#include <functional>
using namespace std;
int V, E, K, a, b, c;
int dist[20001];
vector <pair<int, int> > graph[20001];
priority_queue <pair<int, int>, vector<pair<int,int> >, greater<pair<int,int>> > pq;
int main() {
cin >> V >> E >> K;
for (int i = 0; i < E; i++) {
cin >> a >> b >> c;
graph[a].push_back(make_pair(b, c));
}
fill(dist, dist + 20001, INT_MAX);
pq.push(make_pair(0, K));
dist[K] = 0; // 자기 자신까지의 거리는 0
while (!pq.empty()) {
int mid = pq.top().second, mid_dist = pq.top().first;
pq.pop();
if (dist[mid] > mid_dist) continue; // pq에 저장돼 있는 거리보다 짧은 값이 저장돼 있으면 넘어간다
for (int i = 0; i < graph[mid].size(); i++) {
if (dist[graph[mid][i].first] > dist[mid] + graph[mid][i].second) { // K에서 현재 정점으로 갈 때 거리 > K에서 mid까지 거리 + mid에서 현재 정점까지의 거리
dist[graph[mid][i].first] = dist[mid] + graph[mid][i].second;
pq.push(make_pair(dist[graph[mid][i].first], graph[mid][i].first));
}
}
}
for (int i = 1; i <= V; i++) {
if (dist[i] == INT_MAX) cout << "INF\n";
else cout << dist[i] << "\n";
}
return 0;
}
< JAVA 코드 >
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class BOJ_1753_최단경로 {
static int V, E, K, current, currentWeight, goal, goalWeight, weight;
static int distance[];
static PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2)->o1[1]-o2[1]);
static ArrayList<int[]> graph[];
static int stoi(String st) { return Integer.parseInt(st); }
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
V = stoi(st.nextToken()); E = stoi(st.nextToken()); K = stoi(br.readLine());
distance = new int[V + 1]; graph = new ArrayList[V + 1];
for(int i = 1; i <= V; i++) graph[i] = new ArrayList<>(); // ArrayList 배열로 선언해서 초기화 이렇게 해줌
for(int i = 0; i < E; i++) {
st = new StringTokenizer(br.readLine());
graph[stoi(st.nextToken())].add(new int[] {stoi(st.nextToken()), stoi(st.nextToken())});
} // 입력
Arrays.fill(distance, Integer.MAX_VALUE); // 모든 정점의 값 무한대로 지정
distance[K] = 0; // 시작 정점의 값은 0
pq.offer(new int[] {K, 0}); // 최솟값 정점 찾기 위해 우선순위 큐 사용
while(!pq.isEmpty()) {
current = pq.peek()[0]; currentWeight = pq.poll()[1]; // 경유지
if(currentWeight > distance[current]) continue; // 아까 큐에 넣은 값보다 현재 갱신돼있는 값이 더 작으면 계산할 필요 없으므로 넘김
for(int i = 0; i < graph[current].size(); i++) {
goal = graph[current].get(i)[0];
goalWeight = graph[current].get(i)[1];
if(distance[goal] > distance[current] + goalWeight) {
distance[goal] = distance[current] + goalWeight; // (K->goal) > (K->current + current->goal) 이면 갱신
pq.offer(new int[] {goal, distance[goal]}); // 새 값 넣음
}
}
}
for(int i = 1; i <= V; i++) System.out.println(distance[i] == Integer.MAX_VALUE ? "INF":distance[i]);
}
}
'백준' 카테고리의 다른 글
[백준] 2493번 탑 (JAVA) (0) | 2021.02.07 |
---|---|
[백준] 3085번 사탕 게임 (JAVA) (0) | 2021.02.03 |
[백준] 11062번 카드 게임 (0) | 2020.09.04 |
[백준] 16890번 창업 (0) | 2020.09.01 |
[백준] 1339번 단어 수학 (0) | 2020.08.28 |
Comments