반응형
1. 다익스트라를 이용하여 1번 정점에서 각 정점까지의 거리를 구한다.
2. 늑대의 경우 다익스트라 과정에서 홀수번째로 방문과 짝수번째 방문을 구분해서 기록한다.
1. 다익스트라를 이용하여 1번 정점에서 각 정점까지의 거리를 구한다.
한 정점에서 다른 모든 정점까지의 거리는 다익스트라 알고리즘을 사용하여 구할 수 있다.
2. 늑대의 경우 다익스트라 과정에서 홀수번째로 방문과 짝수번째 방문을 구분해서 기록한다.
늑대의 경우 한 간선을 홀수번째로 이용할 때와 짝수번째로 이용할 때 적용되는 가중치가 다르다. 따라서 한 정점을 홀수번째로 방문할 때와 짝수번째로 방문할 때 거리가 다르므로, dist 배열을 홀수, 짝수 각각 따로 기록해준다. i번 정점까지의 최종거리는 min(i번 정점을 홀수번째로 방문할 때의 거리, i번 정점을 짝수번째로 방문할 때의 거리)가 된다.
반응형
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;
typedef pair<ll, pii> plii;
const ll INF = 987654321;
const int EVEN = 0, ODD = 1;
int N, M;
vector<pii> adjs[4001];
vector<ll> wolfDijkstra(int from) {
vector<ll> ret(N+1);
vector<vector<ll>> dist(2, vector<ll>(N+1, INF));
priority_queue<plii, vector<plii>, greater<plii>> pq;
dist[EVEN][from] = 0;
pq.push({0, {EVEN, from}});
while (!pq.empty()) {
ll d = pq.top().first;
int t = pq.top().second.first;
int newT = 1 - t;
int curr = pq.top().second.second;
pq.pop();
if (d > dist[t][curr]) continue;
for (auto adj: adjs[curr]) {
int next = adj.first;
int c = adj.second;
ll newD = (newT == ODD) ? d+c : d+c*4;
if (newD < dist[newT][next]) {
dist[newT][next] = newD;
pq.push({dist[newT][next], {newT, next}});
}
}
}
for (int i=1; i<=N; i++) {
ret[i] = min(dist[ODD][i], dist[EVEN][i]);
}
return ret;
}
vector<ll> foxDijkstra(int from) {
vector<ll> dist(N+1, INF);
priority_queue<pli, vector<pli>, greater<pli>> pq;
dist[from] = 0;
pq.push({0, from});
while (!pq.empty()) {
ll d = pq.top().first;
int curr = pq.top().second;
pq.pop();
if (d > dist[curr]) continue;
for (auto adj: adjs[curr]) {
int next = adj.first;
int c = adj.second;
ll newD = d + c;
if (newD < dist[next]) {
dist[next] = newD;
pq.push({dist[next], next});
}
}
}
for (int i=0; i<=N; i++) {
dist[i] *= 2;
}
return dist;
}
int solution() {
vector<ll> foxDist = foxDijkstra(1);
vector<ll> wolfDist = wolfDijkstra(1);
int cnt = 0;
for (int i=1; i<=N; i++) {
if (foxDist[i] < wolfDist[i]) cnt++;
}
return cnt;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N >> M;
for (int i=0; i<M; i++) {
int s, e, c;
cin >> s >> e >> c;
adjs[s].push_back({e, c});
adjs[e].push_back({s, c});
}
cout << solution();
return 0;
}
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
백준 5214번 환승 - C++ 풀이 (0) | 2022.08.01 |
---|---|
백준 3745번 오름세 - C++ 풀이 (0) | 2022.07.30 |
백준 23290번 마법사 상어와 복제 - C++ 풀이 (0) | 2022.07.28 |
백준 18809번 Gaaaaaaaaaarden - C++ 풀이 (0) | 2022.07.27 |
백준 1958번 LCS 3 - C++ 풀이 (0) | 2022.07.26 |
댓글