首页 > 其他分享 >7-5 单源最短路径

7-5 单源最短路径

时间:2023-12-23 23:23:13浏览次数:34  
标签:源点 int 路径 单源 continue mp 节点 dis

7-5 单源最短路径

请编写程序求给定正权有向图的单源最短路径长度。图中包含n个顶点,编号为0至n-1,以顶点0作为源点。

输入格式:

输入第一行为两个正整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过1000。接下来e行表示每条边的信息,每行为3个非负整数a、b、c,其中a和b表示该边的端点编号,c表示权值。各边并非按端点编号顺序排列。

输出格式:

输出为一行整数,为按顶点编号顺序排列的源点0到各顶点的最短路径长度(不含源点到源点),每个整数后一个空格。如源点到某顶点无最短路径,则不输出该条路径长度。

输入样例:

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

输出样例:

1 1 

简化版代码

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
using PII = pair<int, int>;

const int INF = 0x3f3f3f3f;
const int N = 2e4 + 10;

vector<pair<int, int>> mp[N];
bool vis[N];
int dis[N];

int main()
{
    memset(dis, INF, sizeof dis);
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m ;++i) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        mp[u].push_back({v, w});
    }
    priority_queue<PII, vector<PII>, greater<PII>> q;
    dis[0] = 0;
    q.push({0, 0});
    while (q.size()) {
        auto [d, u] = q.top();
        q.pop();
        if (vis[u]) continue;
        dis[u] = d;
        vis[u] = true;
        for (auto [v, w] : mp[u]) {
            if (dis[v] < dis[u] + w) continue;
            dis[v] = dis[u] + w;
            q.push({dis[v], v});
        }
    }
    for (int i = 1; i < n; ++i) {
        if (dis[i] == INF) continue;
        printf("%d ", dis[i]);
    }
  
    return 0;
}

中文注释版代码

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
using PII = pair<int, int>;

const int INF = 0x3f3f3f3f;
const int N = 2e4 + 10;

vector<pair<int, int>> mp[N];  // 邻接表存储图的边权信息
bool vis[N];  // 记录节点是否已经被访问
int dis[N];  // 记录源点到各个节点的最短距离

int main()
{
    memset(dis, INF, sizeof dis);  // 初始化距离数组为无穷大
    int n, m;
    scanf("%d %d", &n, &m);

    // 输入边的信息并构建邻接表
    for (int i = 0; i < m ;++i) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        mp[u].push_back({v, w});
    }

    priority_queue<PII, vector<PII>, greater<PII>> q;  // 小顶堆存储节点距离信息
    dis[0] = 0;  // 源点到自身的距离为0
    q.push({0, 0});  // 将源点加入堆中

    while (q.size()) {
        auto [d, u] = q.top();
        q.pop();

        if (vis[u]) continue;  // 如果节点已经被访问过,则跳过

        dis[u] = d;  // 更新最短距离
        vis[u] = true;  // 标记节点已经被访问

        // 遍历与当前节点相邻的节点
        for (auto [v, w] : mp[u]) {
            if (dis[v] < dis[u] + w) continue;  // 如果新的路径没有更短,则跳过
            dis[v] = dis[u] + w;  // 更新最短距离
            q.push({dis[v], v});  // 将新的节点加入堆中
        }
    }

    // 输出从源点到各个节点的最短距离
    for (int i = 1; i < n; ++i) {
        if (dis[i] <span style="font-weight: bold;" class="mark"> INF) continue;  // 如果无法到达该节点,则跳过
        printf("%d ", dis[i]);
    }

    return 0;
}

java版代码(有问题)

注意:运行超时,如果有谁的java代码过了,可以给发在评论区或私信我==

import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    static class Pair implements Comparable<Pair> {
        Integer key;
        Integer value;

        public Pair(Integer key, Integer value) {
            this.key = key;
            this.value = value;
        }

        @Override
        public int compareTo(Pair o) {
            return this.value - o.value;
        }
    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();
        int m = scanner.nextInt();

        int[] dis = new int[n];  // 记录源点到各个节点的最短距离
        Arrays.fill(dis, Integer.MAX_VALUE);  // 初始化距离数组为无穷大

        boolean[] vis = new boolean[n];  // 记录节点是否已经被访问

        ArrayList<Pair>[] mp = new ArrayList[n];  // 邻接表存储图的边权信息
        for (int i = 0; i < n; ++i) {
            mp[i] = new ArrayList<>();
        }

        // 输入边的信息并构建邻接表
        for (int i = 0; i < m; ++i) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            int w = scanner.nextInt();
            mp[u].add(new Pair(v, w));
        }

        PriorityQueue<Pair> q = new PriorityQueue<>();  // 小顶堆存储节点距离信息
        dis[0] = 0;  // 源点到自身的距离为0
        q.add(new Pair(0, 0));  // 将源点加入堆中

        while (!q.isEmpty()) {
            Pair pair = q.poll();
            int d = pair.key;
            int u = pair.value;

            if (vis[u]) continue;  // 如果节点已经被访问过,则跳过

            dis[u] = d;  // 更新最短距离
            vis[u] = true;  // 标记节点已经被访问

            // 遍历与当前节点相邻的节点
            for (Pair edge : mp[u]) {
                int v = edge.key;
                int w = edge.value;
                if (dis[v] < dis[u] + w) continue;  // 如果新的路径没有更短,则跳过
                dis[v] = dis[u] + w;  // 更新最短距离
                q.add(new Pair(dis[v], v));  // 将新的节点加入堆中
            }
        }

        // 输出从源点到各个节点的最短距离
        for (int i = 1; i < n; ++i) {
            if (dis[i] == Integer.MAX_VALUE) continue;  // 如果无法到达该节点,则跳过
            System.out.print(dis[i] + " ");
        }
    }
}

标签:源点,int,路径,单源,continue,mp,节点,dis
From: https://www.cnblogs.com/aslwr/p/75-single-source-the-shortest-path-zmkfes.html

相关文章

  • [C++] 获取工程路径、解决方案路径和.exe路径
    作者:丶布布文章预览:......
  • 风控决策引擎——决策流路径规划
    引言决策引擎服务是风控系统的大脑,承载着风控策略编排和计算的任务,对决策的时耗和精度有着严格的要求,本文以决策流执行路径实现方案为切入点,一窥风控决策引擎高效的原理。背景在上文 风控决策引擎——决策流构建实战 中详细介绍了风控决策引擎的发展历程,决策流的编排能力,满足......
  • EDA365 Skill找不到Cadence安装路径的原因与解决办法
    软件版本Cadence17.4参考来源:https://blog.csdn.net/weixin_42837669/article/details/119832994EDA365Skill安装,无法检测到Cadence安装路径,请确认Cadence软件是否已经安装.以下未尝试 ......
  • 使用OCCT构建两个面之间的最短路径
    查找两个面之间的最短面路径查找面的邻面。std::vector<TopoDS_Face>OCCTUtility::adjacentFace(TopoDS_Faceconst&face,std::optional<TopoDS_Shape>shape,std::optional<TopTools_IndexedDataMapOfShapeListOfShape>edgeMapFace){std::vector<TopoD......
  • pip安装路径由.local调整为/usr/local
    如果没有设置PYTHONUSERBASE,默认会安装在~/.local下如果不希望安装在.local目录下,可以通过配置环境变量PYTHONUSERBASE指定对应的路径,比如/usr/local当然也可以直接修改site.py的_getuserbase方法,通过设置USER_SITE和USER_BASE来指定即调整USERSITE有2种方式:1.设置环境变量P......
  • Leetcode 71. 简化路径
    https://leetcode.cn/problems/simplify-path/description/给你一个字符串path,表示指向某一文件或目录的Unix风格绝对路径(以'/'开头),请你将其转化为更加简洁的规范路径。在Unix风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点(..)表示将目录切换到上一级(指向父目......
  • 轻松管理CRM系统权限!判断文件路径类型,让你更安全
    随着企业客户关系管理(CRM)系统的普及,权限管理成为了系统安全的重要环节。在CRM系统中,我们有时需要设置部分用户账号对某个路径进行读取、写入或执行操作权限。为了实现这一功能,我们需要先判断文件路径是目录还是文件。本文将介绍如何使用Java实现这一功能。一、判断文件路径是目录......
  • 绝对路径和相对路径
    绝对路径和相对路径在Python中,路径分为相对路径和绝对路径。路径:绝对路径相对路径(1)相对路径相对路径是相对于当前工作目录或当前脚本文件所在目录的路径。使用相对路径时,你指定的路径是相对于执行脚本的当前工作目录的。#my_script.pyrelative_path='../data/fi......
  • SpringBoot读取resources下的文件以及resources的资源路径
    1.这种可以但是在容器中获取不到(以下几种都可以只要不在容器)。InputStreaminputStream=this.getClass().getResourceAsStream("/static/imgs/aha.png");Propertiespps=newProperties();Filefile=ResourceUtils.getFile("classpath:defult.properties");pps.loa......
  • 为什么我的请求路径中多了/ 还是能正确请求到我的接口??
    问题:最近测试时发现postman输入了错误了请求路径也能正确路由到我后端的接口,这是为什么呢?举例:请求路径/rest/ceshi/testa/testb?id=1是后端正确的url当把路径中随意/处再增加多个/时,例如请求路径:/rest/ceshi///testa/testb?id=1,任然能正常请求到接口。......