九度OJ-題目1008 最短路徑問題

題目描述:
給你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)
輸出:
輸出 一行有兩個數, 最短距離及其花費。

樣例輸入:
3 2
1 2 5 6
2 3 4 5
1 3
0 0
樣例輸出:
9 11

來源:
2010年浙江大學計算機及軟件工程研究生機試真題

這道題使用Dijkstra最短路徑算法即可,只需多加一個當路徑長度相同時選擇花費最小的判斷。MAX值要設大一點,我一開始設的10000,Wrong Answer。

#include<stdio.h>
#include<string.h>

#define MAX 10000000

int n, m;
int sd = 0, lc = 0;//最短路徑,最少花費
int visited[1001];
int dist[1001][1001];//長度
int cost[1001][1001];//花費
int disp[1001];//st到各個點的最短路徑
int cosp[1001];

int dijk(int st, int en){
    sd= 0;
    lc= 0;
    int u;
    int min;
    int i, j;
    memset(visited, 0, sizeof(visited));
    for(int p= 1; p<= n; p++){
        disp[p]= MAX;
        cosp[p]= MAX;
    }
    disp[st]= 0;//到本身距離爲0
    cosp[st]= 0;
    for(i= 1; i<= n; i++){
        u= -1;
        min= MAX;
        for(j= 1; j<= n; j++){
            if(disp[j]< min && visited[j]== 0){
                min= disp[j];
                u= j;
            }
        }
        if(u== -1){//st點與其他點不相連
            break;
        }
        visited[u]= 1;
        for(int v= 1; v<= n; v++){
            if(dist[u][v]< MAX && visited[v]== 0){
                if(dist[u][v]+ disp[u]< disp[v]){
                    disp[v]= dist[u][v]+ disp[u];
                    cosp[v]= cost[u][v]+ cosp[u];
                }
                else if(dist[u][v]+ disp[u]== disp[v]){
                    if(cost[u][v]+ cosp[u]< cosp[v]){
                        cosp[v]= cost[u][v]+ cosp[u];
                    }
                }
            }
        }
    }
    sd=disp[en];
    lc=cosp[en];
    return 0;
}

int main(){
    int i;
    int a, b, d, p;
    int st, en;
    while(scanf("%d %d", &n, &m)!=EOF){
        if(n==0 && m==0){
            break;
        }
        for(int p= 1; p<= n; p++){
            for(int q= 1; q<= n; q++){
                dist[p][q]= MAX;
                cost[p][q]= MAX;
            }
        }
        for(i= 0; i< m; i++){
            scanf("%d %d %d %d", &a, &b, &d, &p);
            dist[a][b]= d;
            cost[a][b]= p;
            dist[b][a]= d;
            cost[b][a]= p;
        }

        scanf("%d %d", &st, &en);
        dijk(st, en);
        printf("%d %d\n", sd, lc);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章