2022年中国高校计算机大赛上海理工大学校内选拔赛-J史东薇尔城

文章通过C++实现Dijkstra算法,解决了一道在线编程竞赛题目。算法用于找出图中从1号节点到其他所有节点的最短路径,并处理了多个查询,每个查询计算两个指定节点间的最短路径,要求路径必须经过1号节点。
摘要由CSDN通过智能技术生成

题目链接:https://ac.nowcoder.com/acm/contest/52431/J

思路:以1号节点走单源最短路,答案为两个询问点单源最短路之和,若使用另一种方法即SPFA理论得不到全部的分数!!

代码实现:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 100007, M = 100007 << 1;
int n, m;
vector<pair<int, int>> g[N];//邻接表存取无向有权图
bool vis[N];  //记录类似bfs节点是否走过
ll dis[N];
struct node {      
    int v;
    ll w;
    friend bool operator<(const node &a, const node &b) {  //重载小于号比较的是两个节点的权值
        return a.w > b.w;
    }
};
priority_queue<node> pq;//优先队列(小根堆)存取
void dijkstra(int st) {
    for (int i = 1;i <= n;i++) dis[i] = 1e18; //目前求最短路,故首先将每一个节点的距离赋值为一个极大值
    dis[st] = 0;   //初始设为0,距离从0开始加,起始节点为st
    pq.push({ st,0 }); //类似bfs基本思路,首先给优先队列中放入第一个元素
    while (!pq.empty()) {
        int u = pq.top().v; //bfs基本操作
        pq.pop();
        if (vis[u]) continue;//如果遍历过该点,跳出此循环
        vis[u] = 1;
        for (auto [v, w] : g[u]) {//利用C++17的auto快速遍历邻接表(遍历节点u的所有邻居)
            if (dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;     //获取节点u到某一个节点最近的最短路长度
                pq.push({ v,dis[v] });  //继续遍历节点v同u一样,获取v的最短路
            }
        }//直至遍历到终点即已经没有邻居,所有的点都遍历到了,
    }
}


int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);//加快程序的执行速度
    cin >> n >> m;
    for (int i = 1;i <= m;i++) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({ v,w });
        g[v].push_back({ u,w });//无向图基本赋值方法,均赋值u->v,v->u
    }
    dijkstra(1);//从1号节点进行单源最短路遍历
    int T;
    cin >> T;
    while (T--) {
        int s, t;
        cin >> s >> t;
        cout << dis[s] + dis[t] << '\n';   //由题意必须经过节点1,所以和为总的最短路
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值