7-1 最短路徑之Dijkstra (10分)

程式小黃發表於2020-12-12

本題目要求通過讀入無向網的邊的資訊(省略了各頂點的資訊,僅用頂點編號來表示),構造圖,並利用Dijkstra演算法,求出指定源點到其它各點的最短路徑。

輸入樣例:
第一行,兩個整數,頂點數vN和邊數eN。 以後若干行,是相關邊的資訊,無向圖的邊是對稱的,只輸入一半的邊(小編號到大編號的,間以空格),最後兩行各一個整數,前一個指定源點,後一個指定的查詢的終到點。 (注意,示例中34條邊,只輸入了17條邊的資訊)
10 34
0 1 2
0 3 5
1 2 5
1 3 2
2 4 8
2 5 4
3 5 4
3 6 2
4 7 5
4 5 2
5 6 3
5 7 9
5 8 7
6 8 7
7 8 3
7 9 4
8 9 8
0
8
輸出樣例:
在一行中輸出從源點到指定終點的短路徑及代價,注意:所有符號均為西文符號。

0–>1–>3–>6–>8:13

#include<stdio.h>
#define max 1000
#define n 100
void DIJ(float C[n][n],int v,int q)
{
    float D[n];
    int P[n],S[n];
    int i,j,k,v1,pre;
    float min,inf=200;
    v1=v-1;
    for(i=0;i<n;i++)
    {
        D[i]=C[v1][i];
        if(D[i]!=max)
            P[i]=v;
        else P[i]=0;
    }
    for(i=0;i<n;i++)
        S[i]=0;
    S[v1]=1;
    D[v1]=0;
    for(i=0;i<n-1;i++)
    {
        min=inf;
        for(j=0;j<n;j++)
            if((!S[j])&&(D[j]<min))
            {
                min=D[j];
                k=j;
            }
            S[k]=1;
            for(j=0;j<n;j++)
                if((!S[j])&&(D[j]>D[k]+C[k][j]))
                {
                    D[j]=D[k]+C[k][j];
                    P[j]=k+1;
                }
    }
        i=q-1;
        pre=P[i];
        j=0;
        int b[n];
        while(pre!=0)
        {
            b[j]=pre;
            j++;
            pre=P[pre-1];
        }
        printf("%d-->",v-1);
        for(k=j-2;k>=0;k--)
        {
            printf("%d-->",b[k]-1);
        }
        if(D[i]!=max)
        printf("%d:%.0f",i,D[i]);
}
main()
{
    int i,j,k,e,r;
    float z;
    float a[n][n];
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            a[i][j]=max;
    scanf("%d%d",&r,&e);
    for(k=0;k<e/2;k++)
    {
        scanf("%d%d%f",&i,&j,&z);
        a[i][j]=z;
        a[j][i]=z;
    }
    scanf("%d",&i);
    scanf("%d",&j);
    DIJ(a,i+1,j+1);
}

相關文章