1. 程式人生 > >圖結構練習——最短路徑(Dijkstra)

圖結構練習——最短路徑(Dijkstra)

圖結構練習——最短路徑

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

 給定一個帶權無向圖,求節點1到節點n的最短路徑。

Input

 輸入包含多組資料,格式如下。

第一行包括兩個整數n m,代表節點個數和邊的個數。(n<=100)

剩下m行每行3個正整數a b c,代表節點a和節點b之間有一條邊,權值為c。

Output

 每組輸出佔一行,僅輸出從1到n的最短路徑權值。(保證最短路徑存在)

Sample Input

3 2
1 2 1
1 3 1
1 0

Sample Output

1
0
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
int map[105][105];//標示圖的座標
int vis[105];      //表示是否參觀過
int dist[105];      //權值和
void Dijkstra(int n)    //n為終點
{
    int i, j, k, min, u;
    for(i = 1;i <= n;i++)
    {
        dist[i] = map[1][i];//1為起點,將1到的i點得距離存進去
    }
    vis[1] = 1;            //走過的標記
    for(i = 1;i < n;i++)    //進行n-1次查詢,對每個節點都找一次,看有沒有更小的路徑
    {
        min = INF;
        for(j = 1;j <= n;j++)
        {
            if(min > dist[j] && !vis[j])//找出沒有被標記,並且距離起始點最近的點
            {
                min = dist[j];  //記錄大小
                u = j;          //記錄第幾個點
            }
        }
        vis[u] = 1;    //標記一下
        for(k = 1;k <= n;k++)
        { //更新dist的值
            if(!vis[k] && map[u][k] < INF && dist[k] > map[u][k] + dist[u])
            {
                dist[k] = map[u][k] + dist[u];
            }
        }

    }
printf("%d\n",dist[n]);
}
int main()
{
    int n, m, u, v, c, i;
    while(~scanf("%d %d",&n, &m))
    {
        memset(vis,0,sizeof(vis));
        memset(map,INF,sizeof(map));//先全為無窮大
        for(i = 1;i <= n;i++)
        {
            map[i][i] = 0;           //初始化map[][]陣列,除去自己本身,距離為0,其他全設為無窮大
        }
        while(m--)
        {
            scanf("%d %d %d",&u,&v,&c);//輸入
            if(map[u][v] > c)
            {
                map[u][v] = map[v][u] = c;
            }
        }
        Dijkstra(n);//呼叫函式
    }
    return 0;
}

模板程式碼

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
int map[550][550];
int vis[550];
int dist[550];
void  Dijkstra(int n, int s, int d)
{
    int i, j, k, min, u;
    for(i = 0;i< n;i++)
    {
        dist[i] = map[s][i];
    }
    dist[s] = 0;
    vis[s] = 1;
    for(i =1 ;i < n;i++)
    {
        min = INF;
        for(j = 0;j < n;j++)
        {
            if(min > dist[j] && !vis[j])
            {
                min = dist[j];
                u = j;
             }
        }
        vis[u] = 1;
        for(k = 0;k < n;k++)
        {
            if(!vis[k] && map[u][k] < INF && dist[u] + map[u][k] < dist[k])
            {
                dist[k] = dist[u] + map[u][k];
            }
        }
    }
    printf("%d\n",dist[d]);
}