• 算法之迪杰斯特拉(dijkstra)形象化


    用处:求到某点的最短路径

    图形解释:(这里引用一篇大佬写的博客,他写的图形解释非常清晰)

    算法之迪杰斯特拉(dijkstra)非常详细介绍_PRML_MAN的博客-CSDN博客_迪杰斯特拉


    补充理解:

    为了帮助大家理解我这里采用一个

    比喻的例子来帮助大家来理解该算法

    背景引入:

    病毒为了攻占所有的细胞

    偷偷联系一个连通的细胞群

    中的一个间谍细胞体内

    作为初母体

    然后进行它的感染计划

    聪明的它决定感染前找到

    从初母体出发找到

    感染每个细胞的最短路径

    我们可以把要找的某点称为初母体

    在这里插入图片描述

    ( 这里的家就是我们所说的母体)

    这个病毒初母体能够感染

    与它连通一次的所有细胞

    并且在这些所有被感染的细胞中

    找到 和初母体最短距离的细胞(v2细胞)

    在这里插入图片描述

    作为新的母体用来提供感染周围细胞的养分

    提供完后找到距初母体最近的感染细胞

    并因为该细胞被榨干

    废除该细胞为普通感染细胞

    在这里插入图片描述

     

    然后感染未作为母体

    且距离初母体最近的细胞

    作为母体重复下去

    总结下来步骤如下

    1.找到初母体所在位置

    2.母体感染与它连通的所有细胞

    3.废除该母体作为普通细胞

    4.找到距初母体最近的感染细胞(被废除的细胞不能算)

    5.将其作为母体(回到步骤2,直到所有的细胞都被感染结束)


    例题引入:

    为了大家更加理解迪杰斯特拉算法

    这里引入一个题目帮助大家理解

    思路:

    用两次 迪杰斯特拉

    分别找到去和返回的路径的和

    然后比较所有的点来找到所需要走的

    最长路径即可

    注意:

    1. for (int i = 1; i <= n; i++) {
    2. for (int j = i + 1; j <= n; j++) {
    3. //对所有方向进行反向,找到反向后感染最快的路径即到达x点的最短路径所在
    4. swap(tr[i][j], tr[j][i]);
    5. }
    6. }

    这里找返回路径的时候通过

    反转tr就可以实现

    因为反转了所有的方向


    代码详解:

    1. #include
    2. using namespace std;
    3. const int N = 1006;
    4. int d[N],dvis[N],tr[N][N],back[N];
    5. int n, m, x;
    6. void distla() {
    7. memset(dvis, 0, sizeof(dvis));
    8. memset(d, 127, sizeof(d));//赋最大值,表示距离无限远
    9. d[x] = 0;//*让初母体所在位置为0,即从初母体位置开始感染
    10. for (int i = 1; i <= n; i++) {
    11. int index = -1;
    12. for (int j = 1; j <= n; j++)//找出被感染过的最短的路径,并使该点成为新的母体
    13. if (!dvis[j] &&(index == -1 || d[j] < d[index]))
    14. index = j;
    15. dvis[index] = 1;//标记该母体死亡
    16. for (int j = 1; j <= n; j++) {
    17. d[j] = min(d[j],d[index]+tr[index][j]);
    18. //感染母体周围连通且未被感染的点
    19. }
    20. }
    21. }
    22. int main() {
    23. cin >> n >> m >> x;
    24. int t1, t2, t3;
    25. memset(tr, 127, sizeof(tr));
    26. for (int i = 1; i <= m; i++) {
    27. cin >> t1 >> t2 >> t3;
    28. tr[t1][t2] = min(tr[t1][t2],t3);//取t1到t2的最短时间
    29. //标记t1到t2的方向,以及所花费的时间
    30. }
    31. distla();
    32. memcpy(back, d, sizeof(back));//将d数组copy到d数组中
    33. for (int i = 1; i <= n; i++) {
    34. for (int j = i + 1; j <= n; j++) {//对所有方向进行反向,找到反向后感染最快的路径即到达x点的最短路径所在
    35. swap(tr[i][j], tr[j][i]);
    36. }
    37. }
    38. distla();
    39. int maxx = 0;
    40. for (int i = 1; i <= n; i++) {//找到返回和到达的最短路径
    41. maxx = max(d[i] + back[i], maxx);
    42. }
    43. cout << maxx;
    44. return 0;
    45. }

    PS:加油加油加油加油加油

  • 相关阅读:
    延迟任务多种实现姿势--上
    SLAM论文详解(5) — Bundle_Adjustment_LM(BALM)论文详解
    48.排列问题求解
    人工神经网络的训练步骤,神经网络常用训练方法
    JavaScript 中整数的安全范围
    小程序授权获取头像
    如何使用JavaFaker生成模拟数据
    springboot邮件分发
    JavaCard学习笔记: CAP Component 之 Class Component
    端侧模型带来的三个新思考:剪枝、蒸馏、量化
  • 原文地址:https://blog.csdn.net/weixin_60536621/article/details/125990439