BOJ13911

집구하기

문제출처

문제 해석

  • 맥세권과 스세권을 만족하는 집 중 최단 거리의 합이 최소인 집을 구하는 문제입니다.
  • 맥세권: 맥도날드와 집 사이의 최소거리가 X이하인 집
  • 스세권: 스타벅스와 집 사이의 최소거리가 Y이하인 집

설계(20)

  • 맥도날드,스타벅스와 집 사이의 최소 거리를 각각 다익스트라 알고리즘으로 계산합니다.
  • 정해진 X와 Y 이하의 조건을 만족하는 거리 중 최솟값을 갱신합니다.

구현(20)

코드
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
#define MAXN 10000
#define INF 987654321

vector<pair<int, int> > adj[MAXN];
int mac[MAXN];
int sbuk[MAXN];
vector<int> mac_idx;
vector<int> sbuk_idx;
int V, E;
int X, Y;
priority_queue<pair<int, int> > pq;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> V >> E;
	for (int i = 0; i < E; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		u--;
		v--;
		adj[u].push_back({ v,w });
		adj[v].push_back({ u,w });
	}
	int n;
	cin >> n >> X;
	for (int i = 0; i < V; i++) {
		mac[i] = INF;
		sbuk[i] = INF;
	}
	for (int i = 0; i < n; i++) {
		int idx;
		cin >> idx;
		mac_idx.push_back(idx-1);
	}
	cin >> n >> Y;
	for (int i = 0; i < n; i++) {
		int idx;
		cin >> idx;
		sbuk_idx.push_back(idx-1);
	}
	
	for (int i = 0; i < mac_idx.size(); i++) {
		pq.push({ 0,mac_idx[i] });
		mac[mac_idx[i]] = 0;
	}
	while (!pq.empty()) {
		int cur = pq.top().second;
		int cur_w = -pq.top().first;
		pq.pop();
		if (mac[cur] < cur_w) continue;
		for (int i = 0; i < adj[cur].size(); i++) {
			int next = adj[cur][i].first;
			int next_w = adj[cur][i].second + cur_w;
			if (mac[next] > next_w) {
				mac[next] = next_w;
				pq.push({ -next_w,next });
			}		
		}
	}

	for (int i = 0; i < sbuk_idx.size(); i++) {
		pq.push({ 0,sbuk_idx[i] });
		sbuk[sbuk_idx[i]] = 0;
	}
	while (!pq.empty()) {
		int cur = pq.top().second;
		int cur_w = -pq.top().first;
		pq.pop();
		if (sbuk[cur] < cur_w) continue;
		for (int i = 0; i < adj[cur].size(); i++) {
			int next = adj[cur][i].first;
			int next_w = adj[cur][i].second + cur_w;
			if (sbuk[next] > next_w) {
				sbuk[next] = next_w;
				pq.push({ -next_w,next });
			}
		}
	}
	int ans = INF;
	for (int i = 0; i < V; i++) {
		if (mac[i]!= 0 && sbuk[i] != 0 && mac[i] <= X && sbuk[i] <= Y) {
			ans = min(ans, mac[i] + sbuk[i]);
		}
	}
	if (ans == INF) cout << "-1\n";
	else cout << ans << "\n";
	return 0;
}
디버깅
제출결과

124ms

마무리

  • 단순 최단거리를 구하는 문제입니다.