백준 16211번 백채원
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #include <iostream> #include<vector> #include<queue> #include<string> #include<algorithm> #include<cstring> using namespace std; #define MAX 200010 typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const ll INF =321321321321; vector<pll > adj[MAX]; ll dist[MAX+100]; ll dist2[MAX + 100]; bool visited[MAX]; ll N, M,K; void dijkstra(int start) { fill(dist, dist + MAX + 1, INF); priority_queue<pll, vector<pll >, greater<pll> > pq; pq.push({ start,0 }); dist[start] = 0; while (!pq.empty()) { ll here = pq.top().first; ll cost = pq.top().second; pq.pop(); if (dist[here] != cost)continue; for (pll &p : adj[here]) { ll there = p.first; ll new_cost = cost + p.second; if (dist[there] > new_cost) { dist[there] = new_cost; pq.push({ there, new_cost }); } } } } void dijkstra2(vector<ll> arr) { //백채원을 잡는 추종자들 위치를 한꺼번에 //다익스트라로 돌려주면 //dist2[i]에는 우선순위큐에들어간 모든 추종자들중에 i정점에 //제일 가까운추종자의 거리가 들어간다. fill(dist2, dist2 + MAX + 1, INF); priority_queue<pll, vector<pll >, greater<pll> > pq; for (int i = 0; i < arr.size(); i++) { pq.push({ arr[i],0 }); dist2[arr[i]] = 0; } while (!pq.empty()) { ll here = pq.top().first; ll cost = pq.top().second; pq.pop(); if (dist2[here] != cost)continue; for (pll &p : adj[here]) { ll there = p.first; ll new_cost = cost + p.second; if (dist2[there] > new_cost) { dist2[there] = new_cost; pq.push({ there, new_cost }); } } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> M >> K; for (int i = 0; i < M; i++) { int a, b, c; cin >> a >> b >> c; adj[a].push_back({ b,c }); adj[b].push_back({ a,c }); } vector<ll> arr; //백채원을 잡으려는 추종자 위치 벡터 for (int i = 0; i < K; i++) { int a; cin >> a; arr.push_back(a); } dijkstra(1); dijkstra2(arr); priority_queue<int, vector<int >, greater<int> > pq; for (int i = 2; i <= N; i++) { if (dist[i] < dist2[i]) //모든 추종자들보다 백채원이 집에 더 가까운 경우! pq.push(i); } if (pq.empty()) { cout << 0; return 0; } while (!pq.empty()) { cout << pq.top() << " "; pq.pop(); } return 0; } | cs |
출처:https://www.acmicpc.net/problem/16211
MAX값을 2백만으로 잡고 푸니까 배열이 터졌는데 계속 어디가 문제인지 못찾아서 틀렸습니다를 받았네요 ㅋㅋ
이 문제를 풀 때 제일 일반적으로 생각하는 방법은
다익스트라를 추종자들 입장에서 모두 돌려보는 것입니다.
그러나 이렇게 풀게 되면 시간복잡도에서 문제가 터집니다.
1.이 문제를 해결하기 위해서는 추종자들의 모든 위치를 우선순위큐에 넣고 한꺼번에 다익스트라를 실행하는 것입니다.
이렇게 하면 dist2[i]는 모든 추종자들중에 i번 정점에 가까운 거리가 저장되게 됩니다.
왜 이렇게 되는 건지 설명을 하자면 모든 추종자들과의 거리가 0인 가상의 점이 있다고 가정하고,
다익스트라를 돌렸을 때를 생각해보시면 됩니다. 그 가상의 점을 기준으로 다익스트라를 돌렸을 때, 위의 설명과 같은
결과가 나오게 되는 것을 확인 하실 수 있습니다.
'알고리즘 > BAEKJOON' 카테고리의 다른 글
| 백준 9466번 텀 프로젝트 (0) | 2019.05.18 |
|---|---|
| 백준 5719번 거의 최단 경로 (0) | 2019.05.16 |
| 백준 9370번 미확인 도착지 (0) | 2019.05.15 |
| 백준 1504번 특정한 최단 경로 (0) | 2019.05.15 |
| 백준 4486번 녹색 옷을 입은 애가 젤다지? (0) | 2019.05.12 |