Problem Solving/BOJ(백준)

[BOJ]백준 23030번: 후다닥을 이겨 츄르를 받자!(C++)/Dijkstra

이진2 2021. 9. 16. 00:14

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

 

23030번: 후다다닥을 이겨 츄르를 받자!

쿠기는 평소 지하철 최단 경로를 탐색하여 소요 시간을 알려주는 '후다다닥' 어플을 사용 중이다. 그러나 쿠기는 걸음이 너무 느려서 '후다다닥'이 알려주는 경로를 따라가면 항상 지하철이 떠

www.acmicpc.net

좌표가 아닌 지하철 (노선, 역)의 정보를 가진 다익스트라 문제 유형

실제 그래프에 더 가까우니까 사실 다익스트라의 취지(?)에 더 적합한 문제 유형 같당

노선의 역 개수를 입력받아 이차원 벡터를 만들어준 뒤 환승역이 있는 곳에는 이어지는 역에 대한 정보를 넣어주었다

역 사이의 거리는 일정하므로 역 번호의 차를 이용했고

다익스트라 풀이를 위해 해당 노선에 존재하는 환승역들에 대해 탐색을 진행한 뒤 목적지가 같은 노선에 있다면 추가로 우선순위 큐에 넣어주었다(실제 가는 것 보다 환승이 더 빠를 수 있으므로)

#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#define pii pair<int,int>
#define pip pair<int,pii>
#define INF 987654321
using namespace std;

vector<vector<pii>> ds;
vector<vector<int>> ts;
vector<int> stationNum;
int n, m, t, k;

int main() {
	scanf("%d", &n);
	ds = vector<vector<pii>>(n + 1);
	ts = vector<vector<int>>(n + 1);
	stationNum = vector<int>(n + 1);
	for (int i = 1, s; i <= n; i++) {
		scanf("%d", &stationNum[i]);
		ds[i] = vector<pii>(stationNum[i]+1);
	}
	scanf("%d", &m);
	for (int i = 0,p1,p2,q1,q2; i < m; i++) {
		scanf("%d%d%d%d", &p1, &p2, &q1, &q2);
		ts[p1].push_back(p2);
		ts[q1].push_back(q2);
		ds[p1][p2] = make_pair(q1, q2);
		ds[q1][q2] = make_pair(p1, p2);
	}

	scanf("%d", &k);
	while (k--) {
		int u1, u2, v1, v2;

		scanf("%d%d%d%d%d", &t, &u1, &u2, &v1, &v2);

		vector<vector<int>> dist(n + 1);
		priority_queue<pip> pq;
		for (int i = 1; i <= n; i++) {
			dist[i] = vector<int>(stationNum[i]+1, INF);
		}

		pq.push(make_pair(0, make_pair(u1, u2)));
		dist[u1][u2] = 0;

		while (!pq.empty()) {
			int cost = -pq.top().first;
			auto cur = pq.top().second; pq.pop();
			if (cost > dist[cur.first][cur.second])continue;

			for (auto x : ts[cur.first]) {
				auto des = ds[cur.first][x];
				if (dist[des.first][des.second] > dist[cur.first][cur.second] + abs(cur.second - x) + t) {
					dist[des.first][des.second] = dist[cur.first][cur.second] + abs(cur.second - x) + t;
					pq.push(make_pair(-dist[des.first][des.second], des));
				}
			}
			if (cur.first == v1) {
				if (dist[cur.first][v2] > dist[cur.first][cur.second] + abs(cur.second - v2)) {
					dist[cur.first][v2] = dist[cur.first][cur.second] + abs(cur.second - v2);
					pq.push(make_pair(-dist[cur.first][v2], make_pair(cur.first, v2)));
				}
			}

		}

		printf("%d\n", dist[v1][v2]);
	}

	return 0;
}