2087: 算法7-15:迪杰斯特拉最短路径算法

本文深入探讨了迪杰斯特拉算法,一种用于解决单源点最短路径问题的经典算法。详细介绍了算法的工作原理,包括如何初始化距离数组,选择当前最近的节点,更新邻居节点的距离等关键步骤。通过具体的实例,展示了算法的执行过程,帮助读者理解其在实际问题中的应用。

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

题目描述

在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。

在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。

可将迪杰斯特拉算法描述如下:

 

 

void Dijkstra() { for (int i = 0; i < n; i++) {
        dis[i] = inf;
        vis[i] = 0;
    } int i, j, k; 
for (dis[s] = 0, j = 0; j < n; j++) {
     for (k = -1, i = 0; i < n; i++) { 
        if (!vis[i] && (k == -1 || dis[i] < dis[k])) {
                k = i;
            }
        } for (vis[k] = 1, i = 0; i < n; i++) { 
        if (!vis[i] && dis[k] + mp[k][i] < dis[i]) {
                dis[i] = dis[k] + mp[k][i];
            }
        }
    }
}

 

 

在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并按照以上描述中的算法求出源点至每一个其它顶点的最短路径长度。

输入

输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。

以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。

输出

只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。

请注意行尾输出换行。

样例输入

4 1
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0

样例输出

6 4 7 
import java.util.*;
public class Main {
    static int INF=Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n=cin.nextInt();
        int s=cin.nextInt();
        int [][]graph=new int[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                graph[i][j]=cin.nextInt();
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i!=j&&graph[i][j]==0){
                    graph[i][j]=INF;
                }
            }
        }
        //floyd算法求最短距离        for(int k=0;k<n;k++){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    if(graph[i][k]!=INF&&graph[k][j]!=INF){
                        graph[i][j]=Math.min(graph[i][j],graph[i][k]+graph[k][j]);
                    }
                }
            }
        }
        for(int i=0;i<n;i++){
            if(i!=s){
                if(graph[s][i]==INF){
                    System.out.print(-1+" ");
                }
                else{
                    System.out.print(graph[s][i]+" ");
                }
            }

        }

        cin.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值