Codeforces Alpha Round #20
思路:
Dijkstra求最短路,但要求是输出所经过的路径,具体做法我们可以开一个pre数组,在遍历邻接表的时候记录一个点前面的点是哪个,即一个点是从哪个点过来的,然后我们就得到了一个1到n的逆向路径,然后具体得到这个路径可以用一个while循环然后一直用pre数组迭代更新现在的结点,然后依次记录到res数组中,最后不要忘了把一号结点存到res数组,最后再把res数组逆序输出即可
要注意的点就是dist数组要开long long,然后我们可以把传统的Dijkstra算法稍微修改写法,不再把dist值初始化为0x3f,而是初始化成 -1,然后更新dist[j]的时候加一个判断是不是等于-1即可
这个可以当做一个Dijkstra记录最短路径的模板题
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <vector> #include <map> #include <unordered_set> #include <unordered_map> #define x first #define y second #define IOS ios::sync_with_stdio(false);cin.tie(0); using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 100010; const double PI = acos(-1); int n, m; int e[2 * N], ne[2 * N], w[2 * N], h[2 * N], idx; LL dist[N]; int pre[N], res[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; } int dijkstra() { priority_queue<PII, vector<PII>, greater<PII>> heap; memset(dist, -1, sizeof dist); dist[1] = 0; heap.push({0, 1}); while(!heap.empty()) { auto t = heap.top(); heap.pop(); int ver = t.second, distance = t.first; if(st[ver]) continue; st[ver] = true; for (int i = h[ver]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > dist[ver] + w[i] || dist[j] == -1) { dist[j] = dist[ver] + w[i]; heap.push({dist[j], j}); pre[j] = ver; } } } return dist[n]; } int main() { IOS; scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while (m -- ) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c), add(b, a, c); } int t = dijkstra(); if (t == -1) { printf("-1"); return 0; } int now = n, cnt = 0; while (now != 1)//从后往前找路径 { res[cnt++] = now; now = pre[now]; } res[cnt++] = 1; for (int i = cnt - 1; i >= 0; i--) printf("%d ", res[i]); return 0; }

浙公网安备 33010602011771号