dijkstra demo

#include <iostream>
using namespace std;

const int MAX_NUM = 100;
const int MAX_INT = 999999;

// 各数组都从下标1开始
int distArray[MAX_NUM];     // 表示当前点到源点的最短路径长度
int prevArray[MAX_NUM];     // 记录当前点的前一个结点
int map[MAX_NUM][MAX_NUM];   // 记录图的两点间路径长度
int nodeNum, edgeNum;             // 图的结点数和路径数

void Dijkstra(int nodeNum, int srcNode, int *distArray, int *prevArray, int map[MAX_NUM][MAX_NUM])
{
    bool sSet[MAX_NUM];    // 判断是否已存入该点到S集合中
    for (int i = 1; i <= nodeNum; ++i)
    {
        distArray[i] = map[srcNode][i];
        sSet[i] = 0;     // 初始都未用过该点
        if (distArray[i] == MAX_INT)
            prevArray[i] = 0;
        else
            prevArray[i] = srcNode;
    }
    distArray[srcNode] = 0;
    sSet[srcNode] = 1;

    // 依次将未放入S集合的结点中,取distArray[]最小值的结点,放入结合S中
    // 一旦S包含了所有V中顶点,distArray就记录了从源点到所有其他顶点之间的最短路径长度
    // 注意是从第二个节点开始,第一个为源点
    for (int i = 2; i <= nodeNum; ++i)
    {
        int tmp = MAX_INT;
        int u = srcNode;
        // 找出当前未使用的点j的distArray[j]最小值
        for (int j = 1; j <= nodeNum; ++j)
            if ((!sSet[j]) && distArray[j]<tmp)
            {
                u = j;              // u保存当前邻接点中距离最小的点的号码
                tmp = distArray[j];
            }
        sSet[u] = 1;    // 表示u点已存入S集合中

                     // 更新distArray
        for (int j = 1; j <= nodeNum; ++j)
            if ((!sSet[j]) && map[u][j]<MAX_INT)
            {
                int newdist = distArray[u] + map[u][j];
                if (newdist < distArray[j])
                {
                    distArray[j] = newdist;
                    prevArray[j] = u;
                }
            }
    }
}

// 查找从源点srcNode到终点u的路径,并输出
void searchPath(int *prevArray, int srcNode, int destNode)
{
    int pathArray[MAX_NUM];
    int cursor = 1;
    pathArray[cursor] = destNode;
    cursor++;
    int tmp = prevArray[destNode];
    while (tmp != srcNode)
    {
        pathArray[cursor] = tmp;
        cursor++;
        tmp = prevArray[tmp];
    }
    pathArray[cursor] = srcNode;
    for (int i = cursor; i >= 1; --i)
        if (i != 1)
            cout << pathArray[i] << " -> ";
        else
            cout << pathArray[i] << endl;
}

int main()
{
    freopen("input.txt", "r", stdin);
    cin >> nodeNum;
    cin >> edgeNum;
    int p, q, weight;          // 输入p, q两点及其路径长度

                            // 初始化map[][]为MAX_INT
    for (int i = 1; i <= nodeNum; ++i)
        for (int j = 1; j <= nodeNum; ++j)
            map[i][j] = MAX_INT;

    for (int i = 1; i <= edgeNum; ++i)
    {
        cin >> p >> q >> weight;
        if (weight < map[p][q])       // 有重边
        {
            map[p][q] = weight;      // p指向q
            map[q][p] = weight;      // q指向p,这样表示无向图
        }
    }

    for (int i = 1; i <= nodeNum; ++i)
        distArray[i] = MAX_INT;

    for (int i = 1; i <= nodeNum; ++i)
    {
        for (int j = 1; j <= nodeNum; ++j)
            printf("%8d", map[i][j]);
        printf("\nodeNum");
    }

    Dijkstra(nodeNum, 1, distArray, prevArray, map);
    cout << "源点到最后一个顶点的最短路径长度: " << distArray[nodeNum] << endl;
    cout << "源点到最后一个顶点的路径为: ";
    searchPath(prevArray, 1, nodeNum);

    return 0;
}

 

test case

5
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60

 

posted on 2016-10-22 00:51  felacebo  阅读(108)  评论(0)    收藏  举报

导航