單源最短路徑算法---Dijkstra

Dijkstra算法樹解決有向圖G=(V,E)上帶權的單源最短路徑問題,可是要求全部邊的權值非負。html

解題思路:ios

  V表示有向圖的全部頂點集合,S表示那麼一些頂點結合,從源點s到該集合中的頂點的最終最短路徑的權值(程序中用dist[i]表示)已經肯定。算法反覆選擇具備最短路徑估計的頂點u 屬於 V-S(即未肯定最短路徑的點,程序中finish[i]=false的點),並將u加入到S中(用finish[i]=true表示),最後對u的全部輸出邊進行鬆弛。算法

程序實現:spa

     輸入數據:.net

    

5 7code

0 1 100htm

0 2 30blog

0 4 10ip

2 1 60ci

2 3 60

3 1 10

4 3 50

 

/*************************************************************************
    > File Name: Dijkstra.cpp
    > Author: He Xingjie
    > Mail: gxmshxj@163.com
    > Created Time: 2014年06月07日 星期六 22時12分43秒
    > Description: 
 ************************************************************************/
#include<iostream>
#include<cstdio>

using namespace std;

#define INF 99999

//map矩陣記錄路徑圖,dist[i]表示源點到節點
//i的最短路徑,finish[i]表示節點i找到最短路徑
//path[i]=j表示從源節點到i節點的最短路徑要通過j
int map[100][100], dist[100], finish[100];
int path[100];

void Dijkstra(int s, int n)
{
/*
 *s爲源點,n爲節點的個數
 *當finish[i]=true時,dist[i]
 *爲s到i的最短路徑
 *假設S爲已求得最短路徑的終點集合
 *V爲全部節點的集合
 */
    int i, j, v, k;
    
    //初始化dist[i]
    for (i=1; i<n; i++)
    {
        dist[i] = map[s][i];
        if (dist[i] < INF)
            path[i] = s;
    }

    //初始化源節點
    finish[s] = true;
    dist[s] = 0;

    for (i=1; i<n; i++)  //總共有n-1個節點
    {
        int min = INF;
        for (j=0; j<n; j++)      
        {
            //從V-S中(沒有找到最短路徑的集合)尋找離源節點
            //距離最近的點
            if (!finish[j] && dist[j] < min)
            {
                v = j;
                min = dist[j];
            }
        }
        //找到最短路徑
        finish[v] = true;    //把節點v加入到S中
    
        //鬆弛(Relax)
        for (k=0; k<n; k++)
        {
            if (!finish[k] && map[v][k] != INF)
                if (dist[k] > dist[v] + map[v][k])
                {
                    dist[k] = dist[v] + map[v][k];
                    path[k] = v;
                }
        }
    }
}

void PrintPath(int k)
{
    if (k == 0)
    {
        printf("%d", k);
        return;
    }

    PrintPath(path[k]);
    printf("->%d", k);
}

void PrintMap(int n)
{
    int i, j;
    //輸出矩陣
    for (i=0; i<n; i++)
    {
        for (j=0; j<n; j++)
        {
            if (map[i][j] == INF)
                printf("INF ");
            else
                printf("%d  ", map[i][j]);
        }

        printf("\n");
    }
}

int main()
{
    int n, m, i, j;

    freopen("input.txt", "r", stdin);
    cin>>n>>m;    //n是頂點數,m是邊數

    //初始化
    for (i=0; i<n; i++)
    {
        finish[i] = false;
        for (j=0; j<n; j++)
            map[i][j] = INF;
    }

    //輸入
    for(int i=1; i<=m; i++)
    {
        int i,j;
        cin>>i>>j;
        cin>>map[i][j];
    }

    /*
     *PrintMap(n);
     */

    Dijkstra(0, n);

    for (i=1; i<n; i++)
    {
        printf("Path: ");
        PrintPath(i);
        printf("  Dist:%d\n", dist[i]);
    }

    return 0;
}

 

參考:

http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html   

http://blog.csdn.net/hnuzengchao/article/details/7534690

相關文章
相關標籤/搜索