1. 程式人生 > >最短路徑問題(dijkstra,迪傑斯特拉演算法)

最短路徑問題(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