数据结构算法——1088. 最短路径

题目

在这里插入图片描述

思路

dijkstra比较好,通过BFS来不断寻找到n这条路径
需要用road列表(path) 记录前一个点以及 dist列表来记录第一个点到第i个点的距离

由于题目要求问多个最短路径,所以还得需要一个count数组来记录到这个路的最短路径到底有多少条

dijkstra就是先把数据都存放在邻接表上面
然后初始化dist列表,除了自己到自己以外,其他所有的路径初始为INF(无法到达)
然后把自己存入队列{0,1} 0代表距离,1代表去自己本身。
接着根据邻接表依次拿出1结点邻接的点,判断是否来过这个点?如果已经来过这个点了就不要在重复来了,没来过就进行判断。

在这里插入图片描述
判断是否经过这个mid点到end是否比之前到end点更快

代码

#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define INF 0x3f3f3f

struct edge
{
    int end,cost;
};
vector<edge> e[200];
int mark[200];
int road[200];
ll cou[200];
ll dist[200];

void print(int n)
{
    if(n == 0) return;
    print(road[n]);
    cout << n << " ";
}
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i = 0; i < m; i++)
    {
        int start, end, cost;
        cin >> start >> end >> cost;
        e[start].push_back({end,cost});
        e[end].push_back({start,cost});
        //创造邻接表
    }
    priority_queue<pair<int, int>, 
                    vector<pair<int, int>>,
                    greater<pair<int, int>>> que;
    // queue<pair<int,int>> que;
    for(int i = 2; i <= n; i++) dist[i] = INF;
    //初始化点1到其他点的距离
    dist[1] = 0;//到自己肯定是0
    que.push({0,1});//1是距离,2是到哪个点
    cou[1] = 1;//到自己肯定有一种方法
    while(!que.empty())
    {
        int mid = que.top().second;//起始到mid
        que.pop();
        if(mark[mid]) continue;//来过了就别来了
        mark[mid] = true;//记录来过

        for(auto data : e[mid])
        {//bfs来遍历
            int end = data.end;//要去的终点
            int cost = data.cost;//cost
            if(!mark[end])//还没遍历到这个点
            {
                if(dist[end] > dist[mid] + cost)
                {//用if只拿最小部分
                    dist[end] = dist[mid] + cost;
                    cou[end] = cou[mid];//更新路径数量
                    road[end] = mid;//更新路径的一种可能
                    que.push({dist[end], end});//BFS塞进去
                }
                else if(dist[end] == dist[mid] + cost)
                {
                    cou[end] += cou[mid];//加路径
                }
            }
        }
    }
    if(cou[n] == 0)
    {
        cout << -1 << endl;
        cout << 0 << endl;
        cout << -1 << endl;
    }
    else
    {
        cout << dist[n] << endl;
        cout << cou[n] << endl;
        print(n);
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值