AcWing 1129. 热浪(C++)

博客讲述了AcWing平台上的1129题‘热浪’的解题思路,该题目涉及在一个包含T个点和C条无向边的图中,从起点到终点的最短路径问题。博主分析了多种求解最短路的方法,包括朴素Dijkstra、堆优化Dijkstra和SPFA,并提供了C++实现的代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AcWing 1129. 热浪

题意

一个图中有T个点,C条无向边(连接 2 个城镇的道路),再给出一个起点和一个终点,求起点到终点的最短距离(数据保证至少存在一条道路)

分析

一个点到另一个点的最短距离怎么求? 当然是先求这个点到所有点的最短距离,然后就解决了,此题可以使用朴素dijkstra或者堆优化版dijkstra或者spfa,这确实是一道非常裸的求最短路模板题

代码

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int INF = 0x3f3f3f3f, N = 2510, M = 12410;

/*n为点数,m为无向边边数,d[i]表示源点到i号点的距离,
  w,e,ne,h这四个数组是链式前向星数组,idx为使用到的索引,
  x1为起点,x2为终点*/
int n, m, d[N], w[M], e[M], ne[M], h[M], idx, x1, x2;

/*st[i]为true表示i号点在队列中,
  st[i]为false表示i号点不在队列中
*/
bool st[N];

void add(int a, int b, int c) {
    e[++idx] = b;   //e数组存储的是新添加的边的终点
    w[idx] = c;   //w数组存储的是新添加的边的权值
    ne[idx] = h[a];//ne数组存储的是新添加的边的起点的上一条边的编号,如果这个起点只有这么一条边,则h[a]为0
    h[a] = idx; //h[a]表示最新添加的以a为起点的一条边的存储位置,随后cur往下一个位置移动
}

void spfa() {
    memset(d, INF, sizeof d);//初始化源点到所有点的最短距离为无穷大级别
    d[x1] = 0;       //源点到自身的最短距离为0
    queue<int> q;    //声明队列
    q.push(x1);      //把起点入队
    st[x1] = 1;      //标记起点在队列中
    
    while (q.size()) {
        //取出队头,并标记队头不在队列中
        auto t = q.front();
        q.pop();
        st[t] = 0;
        
        //对以t点为起点的出边进行遍历,如果有更短的距离则更新原来的状态
        for (int i = h[t]; i; i = ne[i]) {
            int j = e[i];
            if (d[j] > d[t] + w[i]) {
                d[j] = d[t] + w[i];
                if (!st[j]) {
                    st[j] = 1;
                    q.push(j);
                }
            }
        }
    }
    printf("%d", d[x2]);  //输出源点到终点的最短距离
}

int main() {
    //输入点数和边数,还有起点和终点
    scanf("%d%d%d%d", &n, &m, &x1, &x2);
    
    //输入无向边的信息
    int a, b, c;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
        add(b, a, c);
    }
    spfa();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值