※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 23975번 문제인 정훈이는 민트초코맛 짜장라면이 먹고 싶다이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/23975
23975번: 정훈이는 민트초코맛 짜장라면이 먹고 싶다
첫 줄에 N, M, K가 공백으로 구분되어 주어진다. (1 ≤ N, M, K ≤ 1,000,000) 둘째 줄에 각 편의점에 남아있는 민트초코맛 짜장라면의 개수 Ai가 주어진다. (0 ≤ Ai ≤ 100) 셋째 줄부터 M+2번째 줄까지
www.acmicpc.net
먼저, 각 노드가 주어졌을 때 1번 노드로 돌아가는 경로는 한 가지로 고정된다는 점에 주목하자. 각 길의 거리와 편의점의 규모가 변하지 않기 때문이다.따라서, 편의점의 규모 조건에 유의하여 다익스트라(dijkstra) 알고리즘을 통해 각 노드가 주어졌을 때 집으로 돌아가는 길에 들리게 될 다음 노드를 구할 수 있다.
이 정보들로 1번 노드를 루트로 하고 나머지 각 노드는 최단거리로 1번 노드로 갈 때 다음으로 방문하게 될 노드를 자신의 부모노드로 갖는 형태의 트리를 생각할 수 있다.
이제 이 트리에서, 각 노드가 가리키는 편의점에 재고가 남아있다면 그 재고를 사고, 그렇지 않다면 다음에 이 노드를 경유할 필요가 없다는 점을 기억하면서 쿼리를 처리하는 것으로 문제를 해결할 수 있다. 이는 disjoint set의 구현을 응용하여 간단히 구현할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int cnt[1000001];
int dist[1000001]; // 1번 노드와의 거리
int visited[1000001];
int parent[1000001];
vector<pair<int, int>> G[1000001]; // {node, 두 노드사이 거리}
int findf(int current) {
if (cnt[current]) {
cnt[current]--;
return current;
}
return parent[current] = findf(parent[current]);
}
priority_queue<pair<pair<int, int>,int>> pq; // {{-dist, 노드번호},부모}
void dijkstra() {
pq.push(make_pair(make_pair(0, 1), 0));
while (!pq.empty()) {
int current = pq.top().first.second, d = pq.top().first.first, p = pq.top().second; pq.pop();
if (visited[current]) continue;
dist[current] = -d;
parent[current] = p;
visited[current] = 1;
for (auto node : G[current]) {
int n = node.first, nd = node.second;
pq.push(make_pair(make_pair(d - nd, n), current));
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, M, K; cin >> N >> M >> K;
cnt[0] = 1000000007;
for (int i = 1; i <= N; i++) cin >> cnt[i];
while (M--) {
int x, y, d; cin >> x >> y >> d;
G[x].emplace_back(make_pair(y, d));
G[y].emplace_back(make_pair(x, d));
}
dijkstra();
while (K--) {
int x; cin >> x;
if (x > 1 && dist[x] == 0) cout << -1 << '\n';
else {
int ans = findf(x);
if (ans) cout << ans << '\n';
else cout << -1 << '\n';
}
}
}
'BOJ' 카테고리의 다른 글
[BOJ 23974 // C++] 짝수 게임 (0) | 2022.01.27 |
---|---|
[BOJ 23255 // C++] 구름다리 2 (0) | 2022.01.26 |
[BOJ 7677 // C++] Fibonacci (0) | 2022.01.24 |
[BOJ 7490 // C++] 0 만들기 (0) | 2022.01.23 |
[BOJ 23893 // C++] 알프스의 힘 (0) | 2022.01.22 |