基于leetcode743网络的延迟时间 总结图的最短路径问题(djikstra/djikstra+heap/floyd)

最短路径问题

最短路径问题是图论中典型的问题,可用于解决管道铺设,线路安装,地图规划等路径问题。我们只需考虑有向图的算法,因为无向图是特殊的有向图,我们可以将所有的无向边u<->v,都拆分成两条有向边:u->v和u<-v,为了方便叙述,我们将图中的点数表示为n,图中的边数表示为m

图的存储

一般有两种存储方式:

  1. 邻接矩阵:使用二维数组,w[i] [j]表示点i和点j之间的边权。适用于边数较多的稠密图(当边的数量接近点的数量的平方)使用

    //邻接矩阵数组,w[a][b] = c代表从a到b有权重为c的边,n为点数,m为边数
    int [][]w = new int[n][n];
    //加边操作
    void add(int a,int b,int c){
         
        w[a][b] = c;
    }
    
  2. 邻接表:邻接表有两种常用写法,第二种,代码更简洁,效率也更高:

    1. 二维List<List> edge,edge[i] [j]表示第i个点的第j条邻边

    2. 数组模拟邻接表:为每个点单独开一个单链表,分别存储该点的所有邻边。

      int n,m;//点和边
      int[] ne = new int[m];//存储下一个节点
      int[] he = new int[n];//存储头节点的链表
      int[] e = new int[m];//存储终点节点
      int[] w = new int[m];//存储权重
      int idx;//这里也有一个关键点,idx在类中定义并且不进行赋值,在方法中进行调用,并且在psvm中运行该方法是不会报错的,并且初始值为0
      //a为起点,b为终点,c为权重
      void add(int a,int b,int c){
             
          e[idx] = b;
          ne[idx] = he[a];
          he[a] = idx;
          w[idx] = c;
          idx++;
      }
      

单源最短路+模板

Djikstra算法

最裸的djikstra算法,不使用堆优化

图用邻接矩阵处理

只有所有边的权值为正时才可以使用。稠密图上的时间复杂度为O(n ^ 2),稀疏图上的时间复杂度是O(n^2)

int n,m;
int[][] w = new int[n][n];//存储图的邻接矩阵
int[] dis = new int[n];//dist[]表示每个点到起点的距离
boolean[] keep = new boolean[n];//存储每个点的最短距离是否已经确认
public void djikstra(){
   
    for(int i = 0;i < n;i++){
   
        //给每个点的距离赋值无穷大
        dis[i] = 0x3f3f3f3f;
    }
    dis[1] = 0; 
    for(int i = 0;i < n;i++){
   
        int t = -1;
        //先给第一个节点进行赋值
        for(int j = 1;j <= n;j++){
   
            if(!keep[j]&&(t == -1||dis[j]<dis[t])){
   
                t = j;
            }
        }
        //确认为最短时候更新状态以及余下的节点
        keep[t] = true;
        for(int j = 1;j<=n;j++){
   
            dis[j] = Math.min(dis[j],dis[t]+w[t][j]);
        }
    }
}

Djikstra算法+heap优化

使用邻接表

用堆来维护所有点到起点的距离,时间复杂度为O(nlogn)

class Solution {
   
    int[] ne = new int[6001];
    int[] he = 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值