最短路径问题(dijkstra,迪杰斯特拉算法)

题目描述

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

输入描述:

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

输出描述:

输出 一行有两个数, 最短距离及其花费。
示例1

输入

3 2
1 2 5 6
2 3 4 5
1 3

输出

9 11

代码如下:(一定要注意)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 1005
#define MAX 0x3f3f3f3f
int map[N][N],f[N][N],dis[N],path[N],fee[N],vis[N];
void dijkstra(int s,int t,int n){
    int i,j,v;
    v=s;
    dis[s]=fee[s]=0; vis[s]=1; path[s]=s;
    for(i=1;i<=n;i++)
        if(!vis[i]&&map[s][i]!=MAX){
                dis[i]=map[s][i];
                fee[i]=f[s][i];
                path[i]=s;
        }

    for(i=0;i<n-1;i++){
        int min=MAX;
        for(j=1;j<=n;j++)
            if(!vis[j]&&dis[j]<min){
                min=dis[j];
                v=j;
            }
        if(min==MAX)
            break;
        vis[v]=1;

        for(j=1;j<=n;j++)
            if(!vis[j]&&map[v][j]!=MAX){
                if(dis[j]>dis[v]+map[v][j]){
                    dis[j]=dis[v]+map[v][j];
                    fee[j]=fee[v]+f[v][j];
                    path[j]=v;
                }else if(dis[j]==dis[v]+map[v][j]&&fee[j]>fee[v]+f[v][j]){
                    fee[j]=fee[v]+f[v][j];
                    path[j]=v;
                }
            }
    }
    printf("%d %d\n",dis[t],fee[t]);
}

int main(){
    int n,m,a,b,d,p,s,t,i,j;
    while(scanf("%d %d",&n,&m)!=EOF){
        if(n==0&&m==0)
            break;
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++)
                map[i][j]=f[i][j]=MAX;
            dis[i]=fee[i]=MAX;
            vis[i]=0;
            path[i]=-1;
        }

        while(m--){
            scanf("%d %d %d %d",&a,&b,&d,&p);
            if(map[a][b]>d){
               map[a][b]=map[b][a]=d;
               f[a][b]=f[b][a]=p;
            }else if(map[a][b]==d&&f[a][b]>p)
                f[a][b]=f[b][a]=p;
        }
        scanf("%d %d",&s,&t);
        dijkstra(s,t,n);
    }
    return 0;
}

额外测试数据:

//测试数据   
2 2  
1 2 5 10  
2 1 4 12  
1 2  
4 12  
  
4 4  
1 2 5 6  
2 3 4 5  
1 4 5 10  
4 3 4 2  
1 3  
9 11  
  
6 7  
1 2 5 6  
1 3 5 1  
2 6 2 1  
3 4 1 1  
4 2 1 1  
4 5 1 1  
5 2 3 1  
5 6  
4 3 

猜你喜欢

转载自blog.csdn.net/qq_31342997/article/details/79941100