1. 程式人生 > >HDU2544——最短路(最短路Dijkstra)

HDU2544——最短路(最短路Dijkstra)

題意描述:A,B為路口編號,C為AB之間的權值,計算最短路

/*Dijstra相對於Floyd效率還是高了很多的,它的主題思想為
從源點出發,找距離它最短的一個點,再以這個點為跳板,找離跳板最近的點
當不能繼續進行時,再次回到源點,找第二小的點,重複操作,直到所有的點
都被訪問過為止,注意,每個點只能訪問一次,不然會和Floyd一樣複雜*/ 
#include<cstdio>
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int a[105][105];
//dis為原點到當前點的距離,vis表示訪問狀態
int dis[105],vis[105];
int n,m;
void dijkstra(int x)
{
    int i,j,k;
    for(i=1; i<=n; i++)
    {
        dis[i] = a[x][i];//對dis初始化
    }
    memset(vis,0,sizeof(vis));//0表示沒有被訪問,1表示訪問過
    vis[x] = 1;

    for(i=1; i<n; i++)//迴圈遍數,最多訪問n-1次
    {
        int mix = inf;
        int flag;
        for(j=1; j<=n; j++)
        {
            if(vis[j] ==0&&mix>dis[j])//i=1時找的是離1最近的點,i=2時找的是第二近的點……
            {
                mix=dis[j];//記錄下沒有被訪問,並且最近的點
                flag=j;//標記這個最近的點
            }
        }
        vis[flag] = 1;//標記已經被訪問
        for(k=1; k<=n; k++)
        {
            if(vis[k]==0&&dis[k]>dis[flag]+a[flag][k])
                dis[k] = dis[flag]+a[flag][k];//以該點為跳板
        }
    }
}
int main()
{
    int i,j,k;
    int x,y,z;
    while(cin>>n>>m && n||m)
    {
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
            {
                if(j==i)
                    a[i][j]=0;
                else
                    a[i][j]=inf;
            }
        while(m--)
        {
            cin>>x>>y>>z;
            if(a[x][y]>z)
                a[x][y]=a[y][x]=z;//無向圖
        }
        dijkstra(1);
        cout<<dis[n]<<endl;
    }
    return 0;
}