L2-001 紧急救援(天梯学习)

该代码示例展示了使用Dijkstra算法在C++中找到具有救援队信息的图中两点间的最短路径。程序初始化距离数组、访问标志,并通过遍历更新最短路径及计数。最后,输出最短路径的救援队数量和总和以及路径本身。
摘要由CSDN通过智能技术生成
#include <bits/stdc++.h>

using namespace std;

const int N = 1000;

int g[N][N]; // 记录两条路之间的距离
int cnt[N]; // 通往这条路的最短路的条数
int sum[N]; // 到该点最短路的救援队的数目
int pre[N]; // 记录前驱结点
bool visit[N]; // 记录该点是否已经访问过(false 为没访问过,true 则相反)
int a[N]; // 记录每个城市救援队的数目
int dist[N]; // 记录起始点到该点的距离
int n, m, s, d; // n 是城市的个数  m 是快速道路的条数  s 是出发地的城市编号  d 是目的地的城市编号

void Dijkstra()
{
    memset(dist, 0x3f, sizeof(dist));
    sum[s] = a[s]; // 初始化,sum[s]为0,应该等于起点的救援队数目
    cnt[s] = 1; // 初始化起点到起点算1条路
    dist[s] = 0; // 初始化起点到起点的距离为0
    for(int i = 0; i < n; i ++) // 遍历所有点
    {
        int t = -1; // 用于存储dist最小的点
        for(int j = 0; j < n; j ++) // 遍历所有dist的值
        {
            if(!visit[j] && (t == -1 || dist[t] > dist[j])) 
            {
                t = j;
            }
        }
        visit[t] = true; // 讲选中的点设置为true
        
        for(int j = 0; j < n; j ++) // 遍历j点(起点到该点的距离)与t点(已经是起点到该点距离)的距离的最短路径
        {
            if(dist[j] > dist[t] + g[t][j]) // j点的距离 大于 t点的起点到该点距离 + t到j的距离
            {
                pre[j] = t; // 更新j的前驱结点
                sum[j] = sum[t] + a[j]; // 更新起点到j点的救援队的数目
                cnt[j] = cnt[t]; // 更新起点到j点的条数
                dist[j] = dist[t] + g[t][j]; // 更新起点到j点的距离
            }
            else if(dist[j] == dist[t] + g[t][j]) // j点的距离 等于 t点的起点到该点距离 + t到j的距离
            {
                cnt[j] += cnt[t]; // 更新起点到j点的条数
                if(sum[j] < sum[t] + a[j]) // 起点到j点的救援队的数目 小于 起点到t点的救援队的数目 + j点自身的救援队数目
                {
                    sum[j] = sum[t] + a[j]; // 更新起点到j点的救援队的数目
                    pre[j] = t;// 更新j的前驱结点
                }
            }
        }
    }
    
    cout << cnt[d] << " " << sum[d] <<endl;
    
    int k = d;
    stack<int> stk; // 利用栈来存储最短路
    while(k != s)// 利用先进后出的特点,从终点开始,一次存入该点的前驱结点
    {
        stk.push(k); // 先存入自己本身
        k = pre[k]; // 更新为前驱结点
    }
    
    cout << s; // 因为循环条件的原因,起点没有存入,我们需要额外输出起点
    while(stk.size()) // 依次输出栈点元素
    {
        cout << " " <<stk.top(); 
        stk.pop(); // 将栈顶元素弹出
    }
}

int main()
{
    memset(g, 0x3f, sizeof g); 
    cin >> n >> m >> s >> d; // 题目输入
    
    for(int i = 0; i <n; i ++)
    {
        cin >> a[i]; // 输入每个城市救援队的数目
    }
    
    while(m --)
    {
        int a, b, c; // a 城市1  b 城市2  c 城市1和城市2之间的距离 
        cin >> a >> b >> c; 
        g[a][b] = g[b][a] = c; // 讲数据存入表中g[参数一][参数二] 表示参数一 到 参数二的距离
    }
    Dijkstra();
    return 0;
}

dijkstra最短路求法(非原创,打卡专用)

有错的话,希望大家提醒。有更好做法,欢迎交流。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值