单源最短路径(Dijkstra算法)

声明: 仅个人小记

效果展示:
1.
这里写图片描述

2.
.这里写图片描述
Dijkstra 算法思想:
逐步求解,每步将一条最短路径扩充一条边形成下一条最短路径,并将其他路径替换为更短的

#include <iostream>
#include <vector>
using namespace std;

const int INFINITY = -1; // 记作无穷大  即表示两个顶点之间没有通路 

struct Node{
    int point;// 顶点标号 
    int dist;// 举例 
    vector<int> path;   // 记录路径 
};

void shortestPath(int i); // 顶点 i 出发到达各顶点的最短路径 

int array[5][5] = {
    0,10,-1,30,99,
    -1,0,50,40,-1,
    -1,-1,0,-1,10,
    -1,-1,20,0,60,
    -1,-1,-1,-1,-1
};
/*
    这里对数组array 解释:
        这是一个图的邻接矩阵 
            array[i][j] = n;

            if (n == 0) 
                顶点 i 和 顶点 j 是同一个顶点 
            else if (n > 0) 
                存在从顶点 i 到 顶点 j 的边, 距离为 n 
            else
                不存在从顶点 i 到 顶点 j 的边 
*/ 

int main(void)
{
    shortestPath(3);// 求得从顶点标号为 0 出发的到各顶点最短路径 
    return 0;
}

void shortestPath(int i)
{
    cout << "从顶点 "<<char(i+'A') << " 出发:" << endl;

    Node records[5];// 5 个用来记录 当前顶点 i到各个顶点的最短路径  records这个数组中始终存放的是当前最短路径  

    for (int j = 0; j < 5; j ++) { // 初始化 
        records[j].point = j;
        records[j].dist = array[i][j];
        records[j].path.push_back(j);
    }

    bool flag = false;// 用来反应 最短路径数组是否有发生变化  
    do {
        flag = false;
        for (int j = 0; j < 5; j ++) {
            if (records[j].dist > 0) {// 则可以继续往下走 
                for (int k = 0; k < 5; k ++) {
                    if (array[j][k] > 0) {
                        if ((array[j][k] + records[j].dist) < records[k].dist || records[k].dist == INFINITY) {// 如果发现了一个更短的路径 
                            flag = true;
                            records[k].path = records[j].path;// 实施替换 把原来最短的替换为现在更短的 
                            records[k].path.push_back(k);
                            records[k].dist = array[j][k] + records[j].dist;
                        }
                    }   
                }
            }
        }
    }while(flag);// 如果没有发生变化,说明我们得到了真正的最短路径数组 

    cout << endl << "目标顶点  总路长   轨迹" << endl;

    for (int m = 0; m < 5; m ++) {
        cout << "   " <<char(records[m].point + 'A') << "         " << records[m].dist << "      ";
        for (int n = 0; n < records[m].path.size(); n ++) {
            cout << char(records[m].path[n] + 'A') << "  ";
        }
        cout << endl;
    }
    cout << endl << endl;
    return ;
}

非常有意思,我本以为这个算法需要写不少的代码,实际上,寥寥数笔。

By Jack Lu 2016年11月25日 17:07:53

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值