Floyd算法&&Dijkstra算法

本文详细介绍了Floyd算法和Dijkstra算法的工作原理及应用。Floyd算法是一种利用动态规划寻找有权图多源点间最短路径的方法,而Dijkstra算法则是基于贪心策略寻找单源点到其他各点最短路径的经典算法。文章还提供了两种算法的具体实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Floyd算法和Dijkstra算法

一、Floyd算法

1、简要介绍:Floyd算法又称插点法,是利用动态规划的思想寻找有权图多源点之间最短路径的算法,算法目的是寻找从点i到点j的最短路径。
2、步骤:
以此图为例
以此图为例

Floyd算法核心就是大循环N次下,循环所有点作为一个中转点f,去比较点i到点j的距离和点i到点f的距离加上点f到点j的距离。将较小的值作为点i到点j的距离。
如此图,先从 点1(i = 1)开始,若将点2(k = 2)作为中转点,想要计算的点为点3(j = 3),比较<1,3>的距离和<1, 2> + <2, 3>的距离,结果可知<1, 2> + <2, 3>的距离小于<1,3>的距离,所以<1, 3>的距离变为5。
以此类推,大循环最外围为中转点,内循环为起点和终点,最终可全部遍历。

二、Dijkstra算法

1、简要介绍:Dijkstra算法是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,遍历一遍,判断通过刚刚找到的距离最短的点作为中转点会不会更短,如果更短了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。
2、步骤:
在这里插入图片描述

以此图为例

初始点设为a(i = a),先记录a点到所有点到路径到dis数组,将做过中转点的点做标记;每次找出div中最短的路径,将其点flag做标记,然后比较 <a,j> 的距离和 <a, flag> + <flag, j> 的距离,如果 <a, flag> + <flag, j> 的距离更短,就更新 <a,j> 的距离。循环所有的点作为中转点后,即可求出初始点到所有点到最短路径。

源代码:

#include <iostream>
using namespace std;
#define INF 0x3f3f3f3f
int k, i, j;

//Floyd算法
const int N = 4;
int map[N][N] = {
                    {  0,  2,  6,  4},
                    {INF,  0,  3,INF},
                    {  7,INF,  0,  1},
                    {  5,INF, 12,  0}
};

void Floyd(){
    for(k = 0; k < N; k++){
        for(i = 0; i < N; i++){
            for(j = 0; j < N; j++){
                if(map[i][j] > map[i][k] + map[k][j])
                    map[i][j] = map[i][k] + map[k][j];
            }
        }
    }
    for(i = 0; i < N; i++){
        for(j = 0; j < N; j++){
            if(map[i][j] < 0x3f3f3f3f)
                cout << map[i][j] << " ";
            else
                cout << "# ";
        }
        cout << endl;
    }
}


//Dijkstra算法
const int n = 8;
int d[n][n] = {
                {  0,  1,INF,INF,INF,INF,INF,INF},
                {INF,  0,INF,  2,INF,INF,INF,INF},
                {  2,INF,  0,INF,INF,INF,INF,INF},
                {INF,INF,  1,  0,INF,  8,INF,INF},
                {INF,INF,INF,  2,  0,INF,  2,INF},
                {INF,INF,INF,INF,  2,  0,INF,INF},
                {INF,INF,INF,INF,INF,  3,  0,  3},
                {INF,INF,INF,INF,INF,  2,INF,  0}
    
};
int dis[n] = {0};
int vis[n] = {0};
void Dijkstra(int q){
    //把初始点到所有点的距离计入dis中
    for(i = 0; i< n; i++)
        dis[i] = d[q][i];
    //做过中转点的点vis标记为1
    vis[q] = 1;
    //大循环,共循环n次
    for(int t = 0 ; t < n; t++){
        
        int min = INF;
        int flag = 0;
        //找出dis中最短的距离,并标记所在点
        for(i = 0; i < n; i++){
            if(min > dis[i] && !vis[i]){
                flag = i;
                min = dis[i];
            }
        }
        vis[flag] = 1;
        //如果中转点到i点的距离加上原初始点到falg点的距离
        //小于原初始点到i点的距离就改变dis[i]
        for(i = 0; i < n; i++){
            if(dis[i] > dis[flag] + d[flag][i])
                dis[i] = dis[flag] + d[flag][i];
        }
    }
    //题目要求仅显示0点到n-1点的距离
    cout << dis[n - 1] << endl;
}

int main(){

    cout << "Floyd算法结果:" << endl;
    Floyd();
    cout << "Dijkstra算法结果:" << endl;
    Dijkstra(0);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值