(dijkstra算法+多权值)最短路径问题

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1< n< =1000, 0< m< 100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11

分析与解答

这题我调试了八个小时
我总结一下我对dijkstra的认识

1.dijkstra算法可以求从单个源点出发到所有结点的最短路,这个题就是坑到这了,我写两个参数就wrong answer了,就是说,你调用这个函数只需要一个参数,就是起点。终点是n已经固定了,现在你说终点是t,哪怕走到终点n的路不经过t,你输出dis[t],也是从起点到t的最短路。

《(dijkstra算法+多权值)最短路径问题》

每标记一次就说明被标记的这个数的dis已经确定了。我们循环n次目的就是为了标记n次确定n个数的dis。我们初始化起点的dis是0其他的是inf,我们循环n次,第一个确定下来的就是起点。然后标记,注意这个标记是在那n次循环里的。
2.这个题第二个坑就是,两个点之间的路有多条,如果路的距离相同时,还要找花费最小的

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 100100
using namespace std;

int vis[1100];int dis[1100];
int map[1100][1100];
int value[1100][1100];
int v[1100];
int n;
void dijkstra(int s){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;++i){
        dis[i]=INF;
        v[i]=INF;
    }
    dis[s]=v[s]=0;
    for(int i=1;i<=n;++i){//循环n次,每一次都选一个点标记上
        int x,m=INF;
        for(int y=1;y<=n;++y){//所有未标号节点中选dis最小的结点
            if(!vis[y]&&dis[y]<=m)
            m=dis[x=y];
        }
        vis[x]=1;
        for(int y=1;y<=n;++y)//从x出发的所有边(x,y),更新dis[y]
        { 
            if (dis[y] > dis[x] + map[x][y]){
                dis[y]= dis[x]+map[x][y];
                v[y] = v[x] + value[x][y];
            }
            else if (dis[y] == dis[x] + map[x][y] && v[y] > v[x] + value[x][y]){
                v[y] = v[x] + value[x][y];
            }
        }
    }
}

int main() {
    int m;
    int a,b,c,p;
    int s,t;
    while(cin>>n>>m){
        if(m==0&&n==0) return 0;
        //
       // memset(v,INF,sizeof(v));
        memset(map,INF,sizeof(map));
        memset(value,INF,sizeof(value));
        for(int i=0;i<m;++i){
            scanf("%d%d%d%d",&a,&b,&c,&p);
            if(c<map[a][b]){
                map[a][b]=map[b][a]=c;
                value[a][b]=value[b][a]=p;
            }
            if(c==map[a][b]&&value[a][b]>p){
                value[b][a]=value[a][b]=p;
            }

        }
        scanf("%d%d",&s,&t);
        dijkstra(s);
        printf("%d %d\n",dis[t],v[t]);
    }
} 
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/qq_40828914/article/details/81637126
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞