图-最短路径

最短路径:对于网图来说,最短路径是指两个顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点式源点,最后一个顶点是终点。以下图为例,

 寻找v0到v8的最短距离。

对应解决思路:现在比较成熟的有Dijkstra(迪杰斯特拉)算法Flord算法算法。

Dijkstra(迪杰斯特拉)算法

Dijkstra求源节点S到终结点D的最短距离的过程中,循环过程中每次确定一个源节点到其它节点T的最短距离。该距离确定后,遍历判断该节点T到其它节点的距离是否比现在S到其它节点距离短,更短的话则修改为相应长度,并将对应的路径记录。。这种求最短路径的方式与图最小生成树算法之Kruskal(克鲁斯卡尔)算法有异曲同工之妙。该算法的时间复杂度度是O(N^2),N是节点的个数。

代码如下:


int dist[MAXNUM];

int prevT[MAXNUM];

int final[MAXNUM];

int MIN;

int G[9][9]={0,1, 5, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT, MAXINT,//对应的权值矩阵

             1, 0, 3, 7, 5, MAXINT ,MAXINT, MAXINT ,MAXINT,

             5 ,3, 0, MAXINT ,1 ,7, MAXINT ,MAXINT ,MAXINT,

            MAXINT, 7, MAXINT ,0, 2, MAXINT, 3 ,MAXINT, MAXINT,

            MAXINT ,5, 1, 2, 0, 3 ,6, 9, MAXINT,

            MAXINT, MAXINT ,7, MAXINT, 3, 0, MAXINT, 5, MAXINT,

            MAXINT ,MAXINT ,MAXINT,  3, 6, MAXINT, 0 ,2 ,7,

            MAXINT, MAXINT ,MAXINT, MAXINT, 9 ,5 ,2, 0, 4,

            MAXINT, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT ,7, 4, 0};
void Short_Dijkstra()
{
    //初始化dist和prevT
    int min_num;
    for(int i=0;i<MAXNUM;i++)
    {
      final[i]=0;//标记是否是最短路径
      dist[i]=G[0][i];//对应权值
      prevT[i]=0;
    }
    final[0]=1;//对v0本身就是最短的
    dist[0]=G[0][0];
    for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离
    {
        MIN=MAXINT;//最小值
        min_num=0;
        for(int j=1;j<MAXNUM;j++)
        {
            if(!final[j] &&  dist[j]<MIN)
            {
                min_num=j;
                MIN=dist[j];//最小值
            }
        }
        final[min_num]=1;//找到最小值
       for(int k=0;k<MAXNUM;k++)
       {
          if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离
           {
               prevT[k]=min_num;//记录经过的前驱点
               dist[k]=G[min_num][k]+dist[min_num];//更新距离
          }
       }
    }
}

Flord算法

Floyd算法是一个经典的动态规划算法,它适用于寻找各个顶点之间的最短距离。从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从点i到点j,这种方法最直接,但是距离比一定最短。2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点i到节点j的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),同时记录我们走过的路径。这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。算法时间复杂度:O(n3)。

代码如下

void Short_Dijkstra()
{
    //初始化dist和prevTT
    int min_num;
    for(int i=0;i<MAXNUM;i++)
    {
      final[i]=0;
      dist[i]=G[0][i];
      prevT[i]=0;
    }
    final[0]=1;//对v0本身就是最短的
    dist[0]=G[0][0];
    for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离
    {
        MIN=MAXINT;//最小值
        min_num=0;
        for(int j=1;j<MAXNUM;j++)
        {
            if(!final[j] &&  dist[j]<MIN)
            {
                min_num=j;
                MIN=dist[j];//最小值
            }
        }
        final[min_num]=1;//找到最小值
       for(int k=0;k<MAXNUM;k++)
       {
          if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离
           {
               prevT[k]=min_num;//记录经过的前驱点
               dist[k]=G[min_num][k]+dist[min_num];//更新距离
          }
       }
    }
}

图这两种算法最核心的思想就是:利用已有的最短的距离路径,通过这路径来不断扩充,最终实现从原点S到终点D的寻找过程。

时间: 2024-08-10 23:27:53

图-最短路径的相关文章

hdu1818 It&#39;s not a Bug, It&#39;s a Feature!(隐式图最短路径Dijkstra)

题目链接:点击打开链接 题目描述:补丁在修bug时,有时也会引入新的bug,假设有n(n<=20)个潜在的bug和m(m<=100)个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug.第一个串表示打补丁之前的状态('-'表示在该位置不存在bug,'+'表示该位置必须存在bug,0表示无所谓),第二个串表示打补丁之后的状态('-'表示不存在,'+'表示存在,0表示不变).每个补丁都有一个执行时间,你的任务是用最少的时间把一个所有bug都存在的软件通过打补丁的方式变得没

数据结构——图——最短路径D&amp;F算法

一.Dijkstra算法(贪心地求最短距离的算法) 在此算法中,我按照自己的理解去命名,理解起来会轻松一些. #define MAXSIZE 100 #define UNVISITED 0 #define VISITED 1 #define INFINITY 66666 typedef struct tool { int visited[MAXSIZE]; /*是否已访问的数组,visited[i]表示顶点i已经访问,也就是到顶点i的最短距离已求出*/ int known_shortest_di

数据结构(五)图---最短路径(弗洛伊德算法)

一:定义 弗洛伊德算法是用来求所有顶点到所有顶点的时间复杂度. 虽然我们可以直接对每个顶点通过迪杰斯特拉算法求得所有的顶点到所有顶点的时间复杂度,时间复杂度为O(n*3),但是弗洛伊德算法更加简洁优雅 二:弗洛伊德的使用介绍 若是求一个顶点到其他顶点的最短距离,例如迪杰斯特拉算法,我们的距离数组和路径数组使用一维即可,但是我们这里是获取所有顶点到其余顶点的最短距离,所以我们对于数组和路径都需要使用二维数组来表示 下面我们使用一个有三个顶点的图来进行讲解: (1)我们先定义两个二维数组D0[3][

图-最短路径-Dijkstra及其变种

目录 最短路径 Dijkstra 算法 算法思想 具体实现 最短路径 Dijkstra+DFS 最短路径 最短路径问题: 给定任意的图G(V,E) 和起点 S,终点 T,如何求从 S 到 T 的最短路径. 解决最短路径的常用方法有 Dijkstra 算法 Bellman-Ford 算法 SPFA 算法 Floyd 算法 这里主要对 Dijkstra 算法及其变种进行总结. Dijkstra 算法 算法思想 Dijkstra 算法用来解决单源最短路径问题,即给定图 G 和起点 s,通过算法得到 S

Dijkstra含权图最短路径;审判,不要错过枚举退款保证不会重复;国际象棋八皇后问题

求两节点的最短通路.对于无权图,能够通过图的广度优先遍历求解.含权图一般通过Dijkstra算法求解. import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class Shortest { static class Cell{ int node;//连接到哪个节点 int weight

java数据结构和算法------图(最短路径Dijkstra)

1 package iYou.neugle.graph; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 //创建图过程的代码在图的那篇博文中,此处直接使用 7 public class Dijkstra { 8 private MyGraph1 graph; 9 private int start; 10 private int maxNum; 11 private int[] distance;// 起始点到终点距离

图-最短路径问题

从某个源点到其余各顶点的最短路径 迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法是一个按路径长度递增的次序产生最短路径的算法.(负值圈该算法无效) 算法描述: 假设用带权的邻接矩阵 arcs表示带权有向图,arcs[i][j]表示弧<vi,vj>上的权值:若<vi,vj>不存在,则arcs[i][j]为∞,S为已找到的从v0顶点出发的最短路径的终点的集合,初始状态为空. 选择 v0到 V-S中顶点构成的最短路径<v0,vj>,并将vj加入S. 由于vj加入到S中,最

洛谷图论入门题--基本题必做 图-最短路径-1.信使(msner)

1 //带病打代码的我,心好累,脑子更累. 看到此代码的请给点个赞 ,谢谢. 2 //这个题还是比较简单的,用弗洛伊德完全就能过: 3 /*由衷的感谢江山,帮忙看程序的错误 , 4 5 ,--^----------,--------,-----,-------^--, 6 | ||||||||| `--------' | O 7 `+---------------------------^----------| 8 `\_,-------, _________________________|

数据结构--图(中)--最短路径问题

最短路径问题 最短路径: 边上的权重就是距离. 最便宜: 权重是价格. 最快的路径: 通过结点最少 最短路径问题的抽象 在网络中,求两个不通顶点之间的所有路径中,边的权值之和最小的那一条路径 这条路径就是两点之间的最短路径 第一个顶点为源点 最后一个顶点为终点 问题分类 单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径. (有向)无权图 (有向)有权图 多源最短路径问题:求任意两顶点间的最短路径. 单源最短路径在每个节点上用一遍就是多源最短路径. 单源无权图 最短路径问题 思路是