Codeforces Alpha Round #20

C. Dijkstra?

思路:

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;
}

 

posted @ 2021-10-29 22:28  彦辰kkkkk  阅读(72)  评论(0)    收藏  举报