문제:icpc.me/9370
시작지점이 주어지고 이들의 도착 예정 경로들이 주어진다.
이 때 주어진 도착 예정 경로로는 무조건 최단경로로 이동할 때 어떤 한 간선을 통과하는지 여부를 묻는 문제이다.
우리는 시작지점에서 다익스트라를 실행하여 모든 정점으로의 최단거리를 전부 계산해준 뒤 주어진 간선에서 부터 다시 다익스트라를 실행하여 주어진 간선에서 부터의 최단 거리를 구해준다.
그리고 나서 도착 예정경로중 (시작정점에서 도착 예상 정점의 최단거리 = 시작정점에서 주어진 간선까지의 최단거리 + 주어진간선부터 도착 예상정점으로의 최단거리) 인 정점들을 출력해주면 된다.
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 | #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cstring> using namespace std; int T, n, m, t, s, g, h, a, b, d, xd[2020], yd[2020], f[2020]; vector<vector<pair<int, int>>> vt; void dijkstra(int start, int *dist) { priority_queue<pair<int, int>> pq; pq.push({ 0,start }); while (pq.size()) { int here = pq.top().second; int cost = -pq.top().first; pq.pop(); if (dist[here] != -1)continue; dist[here] = cost; for (auto next : vt[here]) { if (dist[next.first] != -1)continue; pq.push({ -cost - next.second,next.first }); } } } int main() { scanf("%d", &T); while (T--) { scanf("%d%d%d%d%d%d", &n, &m, &t, &s, &g, &h); vt.clear(); vt.resize(n + 1); memset(f, 0, sizeof(f)); memset(xd, -1, sizeof(xd)); memset(yd, -1, sizeof(yd)); for (int i = 0; i < m; i++) { scanf("%d%d%d", &a, &b, &d); vt[a].push_back({ b,d }); vt[b].push_back({ a,d }); } for (int i = 0; i < t; i++) { scanf("%d", &a); f[a] = 1; } dijkstra(s, xd); int bridge = xd[g] < xd[h] ? h : g; dijkstra(bridge, yd); for (int i = 1; i <= n; i++) { if (!f[i])continue; if (xd[i] == -1 || yd[i] == -1)continue; if (xd[i] == xd[bridge] + yd[i]) printf("%d ", i); } puts(""); } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)11409 열혈강호 6 (0) | 2017.03.09 |
---|---|
BOJ)11408 열혈강호5 (0) | 2017.03.09 |
BOJ)1252 이진수 덧셈 (0) | 2017.03.07 |
BOJ)2636 치즈 (0) | 2017.03.06 |
BOJ)1629 곱셈 (0) | 2017.03.05 |