题解 | #最短路径问题#Dijkstra算法#最详细

最短路径问题

https://www.nowcoder.com/practice/e372b623d0874ce2915c663d881a3ff2

本题为单源最短路径问题,故可以考虑使用迪杰斯特拉算法,传入一个整型变量作为起点,同时维护两个全局记录最短距离和最小花费的数组。在迪杰斯特拉算法的内部,通过对邻接表的遍历更新这两个数组,遍历完成后数组下标对应的元素即为所得,打印即可。详细算法步骤见注释

#include <bits/stdc++.h>

using namespace std;
int MAXNUM = 1010;
int INF=INT_MAX;

struct Edge {//边表,记录目标节点,路径长度,花费
    int to;
    int length;
    int price;

    Edge(int _t, int _l, int _p) {//构造函数,简化后续
        to = _t;
        length = _l;
        price = _p;
    }
};
struct QueueNode{//在优先队列中的节点,记录当前节点出发到各个节点的距离
    int number;
    int distance;
    QueueNode(int _n,int _d){
        number = _n;
        distance = _d;
    }
    bool operator<(const QueueNode& p)const{//重载运算符。将小于号重载为大于号
        return distance>p.distance;
    }
};
vector<Edge> graph[1010];//邻接表,graph[i][]表示从i节点开始的边数
int minDistance[1010];//最小距离数组
int cost[1010];//最小花费数组

void Dijkstra(int start){
    minDistance[start]=0;//初始化,将起始点到自己的距离和花费都变成0
    cost[start]=0;
    priority_queue<QueueNode> MyPriQue;//新建优先队列,运算符已经重载了,变成升序序列
    MyPriQue.push(QueueNode(start,minDistance[start]));//起始节点入队
    while(!MyPriQue.empty()) {//优先队列为空时停止循环
        int u = MyPriQue.top().number;//记录离原点最近的点
        MyPriQue.pop();//弹出队首元素
        for(int i=0;i<graph[u].size();i++){ //遍历当前节点u的邻接边表
            int v = graph[u][i].to;//to代表目标的节点
            int l = graph[u][i].length;
            int p = graph[u][i].price;
if((minDistance[v]==minDistance[u]+l&&cost[v]>cost[u]+p)||minDistance[v]>minDistance[u]+l){
                minDistance[v]=minDistance[u]+l;//若出发点到v的距离大于途径u到v的距离,或者相等条件下小于途径u到v的花费,就将v对应的mindistance和cost进行修改,并把v重新压入优先队列中。
                cost[v]=cost[u]+p;
                MyPriQue.push(QueueNode(v,minDistance[v]));
            }
        }
    }
    return;
}

int main() {
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0&&m==0){
            break;
        }
        memset(graph,0,sizeof(graph));//初始化邻接表
        fill(minDistance, minDistance+n+1,INF);//初始化两个数组,fill()函数是algorithm头文件定义的函数。fill(a.begin(),a.end(),INF)为用法,这里使用数组首地址和首地址+整形表示数组长度,参数一定要用地址!
        fill(cost,cost+n+1,INF);
        while(m--){
            int to,from,distance,costt;
            scanf("%d%d%d%d",&to,&from,&distance,&costt);
            graph[to].push_back(Edge(from,distance,costt));//无向图,故每一条边需要对两个端点分别存一下邻接表。
            graph[from].push_back((Edge(to,distance,costt)));
        }
        int start,end;//读取起始节点和终止节点
        scanf("%d%d",&start,&end);
        Dijkstra(start);//调用最短路径算法
        printf("%d %d\n", minDistance[end], cost[end]);//直接打印终止节点对应的distanc和cost值即可
    }
    return 0;
}

全部评论

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
11-24 11:23
门头沟学院 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务