浙大陈越何钦铭数据结构07-图6 旅游规划

news2025/1/23 7:20:33

题目:

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出样例:
3 40

代码及注释:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_VERTEX_NUM 500
#define MAX_DIST 501
#define MAX_COST 501
#define ERROR -1

typedef int Vertex;

struct _Edge
{
    Vertex V, W;
    int dist, cost;
};
typedef struct _Edge *Edge;

struct _MGraph
{
    int Nv, Ne;
    int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int cost[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
};
typedef struct _MGraph *MGraph; /* 以邻接矩阵存储的图的类型  */

void InsertEdge(MGraph G, Edge E); // 插入边
MGraph CreateGraph(int vertexNum); // 初始化图
MGraph BuildGraph();

Vertex FindMinDist(MGraph G, int dist[], bool collected[]);
void Dijkstra(MGraph G, int dist[], int cost[], Vertex S);

Vertex src, dst;
// 对于全局的int数组自动初始化为0,bool数组初始化为false
int dist[MAX_VERTEX_NUM];
int cost[MAX_VERTEX_NUM];
bool collected[MAX_VERTEX_NUM];

/*
07-图6 旅游规划
https://pintia.cn/problem-sets/1667128414987735040/exam/problems/1667128415088398337

难度:2颗星

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

3 40
 */

int main()
{
    MGraph G = BuildGraph();
    Dijkstra(G, dist, cost, src);
    printf("%d %d\n", dist[dst], cost[dst]);
    free(G);

    return 0;
}

MGraph CreateGraph(int vertexNum)
{
    MGraph G = (MGraph)malloc(sizeof(struct _MGraph));
    G->Nv = vertexNum;
    G->Ne = 0;
    Vertex V, W;

    for (V = 0; V < vertexNum; V++)
    {
        for (W = 0; W < vertexNum; W++)
        {
            G->dist[V][W] = MAX_DIST;
            G->cost[V][W] = MAX_COST;
        }
    }

    return G;
}

void InsertEdge(MGraph G, Edge E)
{
    /* 插入边<V,W> */
    G->dist[E->V][E->W] = E->dist;
    G->cost[E->V][E->W] = E->cost;

    /* 若是无向图则要反向也插入 */
    G->dist[E->W][E->V] = E->dist;
    G->cost[E->W][E->V] = E->cost;
}

MGraph BuildGraph()
{
    MGraph G;
    Edge E;
    int Nv, Ne;
    scanf("%d %d %d %d", &Nv, &Ne, &src, &dst);
    G = CreateGraph(Nv);
    if (Ne)
    {
        G->Ne = Ne;
        E = (Edge)malloc(sizeof(struct _Edge));

        for (int i = 0; i < G->Ne; i++)
        {
            scanf("%d %d %d %d", &E->V, &E->W, &E->dist, &E->cost);
            InsertEdge(G, E);
        }

        free(E);
    }

    return G;
}

Vertex FindMinDist(MGraph G, int dist[], bool collected[])
{ /* 返回未被收录顶点中dist最小者 */
    Vertex minV = ERROR;
    int minDist = MAX_DIST;

    for (Vertex V = 0; V < G->Nv; V++)
    {
        if (collected[V] == false && minDist > dist[V])
        {
            /* 若V未被收录,且dist[V]更小 */
            minDist = dist[V]; /* 更新最小距离 */
            minV = V;          /* 更新对应顶点 */
        }
    }
    
    if (minDist < MAX_DIST) /* 若找到最小dist */
        return minV;        /* 返回对应的顶点下标 */
    else
        return ERROR; /* 若这样的顶点不存在,返回错误标记 */
}

void Dijkstra(MGraph G, int dist[], int cost[], Vertex S)
{
    Vertex V, W;

    /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
    for (V = 0; V < G->Nv; V++)
    {
        dist[V] = G->dist[S][V];
        cost[V] = G->cost[S][V];
    }
    /* 先将起点收入集合 */
    dist[S] = 0;
    collected[S] = true;

    while (1)
    {
        /* V = 未被收录顶点中dist最小者 */
        V = FindMinDist(G, dist, collected);
        if (V == ERROR)      /* 若这样的V不存在 */
            break;           /* 算法结束 */
        collected[V] = true; /* 收录V */

        for (W = 0; W < G->Nv; W++) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未被收录 */
            if (collected[W] == false && G->dist[V][W] < MAX_DIST)
            {
                if (G->dist[V][W] < 0) /* 若有负边 */
                    return;            /* 不能正确解决,返回错误标记 */
                /* 若收录V使得dist[W]变小 */
                if (dist[V] + G->dist[V][W] < dist[W])
                {
                    dist[W] = dist[V] + G->dist[V][W]; /* 更新dist[W] */
                    cost[W] = cost[V] + G->cost[V][W];
                }
                else if (dist[V] + G->dist[V][W] == dist[W] &&
                         cost[V] + G->cost[V][W] < cost[W])
                {
                    cost[W] = cost[V] + G->cost[V][W];
                }
            }
    } /* while结束*/
}

ChatGPT对代码的分析,评估:

定义了合适的常量:MAX_DIST 和 MAX_COST 的定义符合题目要求,对于表示距离和花费的最大值都设置为 501,有效地区分了有限距离和无穷远的情况。

创建图和插入边:CreateGraph 和 InsertEdge 函数用于创建图和插入边的操作,实现了初始化图的邻接矩阵并向图中添加边的功能。

构建图:BuildGraph 函数根据输入构建了图,并通过调用 CreateGraph 和 InsertEdge 来创建和填充图的邻接矩阵。

Dijkstra 算法:Dijkstra 函数使用 Dijkstra 算法,根据图的邻接矩阵计算从起点到每个顶点的最短距离和最小花费。在这个过程中,使用了辅助函数 FindMinDist 来选择未被收录顶点中距离最小的顶点。

主函数运行:主函数中先调用 BuildGraph 构建图,然后调用 Dijkstra 计算最短距离和最小花费,并输出结果。

执行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/924754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汽车电子笔记之:AUTOSA架构下的OS概述

目录 1、实时操作系统&#xff08;RTOS&#xff09; 2、OSEK操作系统 2.1、OSEK概述 2.2、OSEK处理等级 2.3、OSEK任务符合类 2.4、OSEK优先级天花板模式 3、AUTOSAR OS 3.1、 AUTOSAR OS对OSEK OS的继承和扩展 3.2、AUTOSAR OS的调度表 3.3、AUTOSAR OS的时间保护 3…

PID直观感受简述

0、仿真控制框图 1、增加p的作用&#xff08;增加响应&#xff09;P 2、增加I的作用&#xff08;消除稳差&#xff09;PI 3、增加D的作用&#xff08;抑制波动&#xff09;PID 加入对噪声很敏 4、综合比对

java maven项目打jar包发布(精简版)

目录 一、maven打包 二、安装jdk环境 三、安装mysql 四、jar包传输到服务器 一、maven打包 先clean再package target文件夹下面有生成一个jar包 二、安装jdk环境 1、下载jdk cd /usr/local wget https://repo.huaweicloud.com/java/jdk/8u201-b09/jdk-8u201-linux-x64.tar.…

[谦实思纪 02]整理自2023雷军年度演讲——《成长》(下篇)创业之旅(创业与成长)

文章目录 [谦实思纪]整理自2023雷军年度演讲 ——《成长》&#xff08;下篇&#xff09;创业之旅&#xff08;创业与成长&#xff09;0. 写在前面1. 创业&#xff01;&#xff08;创业与成长&#xff09;1.1 找互补的朋友一起干&#xff0c;更容易成功1.2 创业中必须要有领导者…

Verilog 基础语法(题目)

Verilog 基础语法&#xff08;题目&#xff09; **本内容来自 牛客网Verilog基础语法** 1、四选一多路器 制作一个四选一的多路选择器&#xff0c;要求输出定义上为线网类型 状态转换&#xff1a; d0 11 d1 10 d2 01 d3 00 信号示意图&#xff1a; 波形示意图&#xff1a; …

抖音seo矩阵系统源代码开发部署分享

一、 开发步骤分享 抖音SEO矩阵系统源代码开发部署分享&#xff0c;需要经验丰富的开发人员和服务器管理人员&#xff0c;以下是大致的步骤&#xff1a; 确定你需要的功能和设计&#xff0c;确定开发人员和设计师的角色和任务分配&#xff0c;以及开发进度和计划。 确定服务器…

分类预测 | MATLAB实现MIV-SVM的平均影响值MIV算法结合支持向量机分类预测

分类预测 | MATLAB实现MIV-SVM的平均影响值MIV算法结合支持向量机分类预测 目录 分类预测 | MATLAB实现MIV-SVM的平均影响值MIV算法结合支持向量机分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 先利用平均影响值MIV算法对特征进行排序&#xff0c;确定分类特征…

SimpleDateFormat 是线程安全的吗?使用时应该注意什么?面试回答

面试回答 在日常开发中&#xff0c;我们经常用到时间&#xff0c;我们有很多办法在 Java 代码中获取时间。但是不同的方法获取到的时间的格式都不尽相同&#xff0c;这时候就需要一种格式化工具&#xff0c;把时间显示成我们需要的格式。 最常用的方法就是使用 SimpleDateForm…

leetcode 718. 最长重复子数组

2023.8.24 本题求得子数组&#xff0c;其实就是连续的序列。定义一个二维dp数组&#xff0c;dp[i][j]的含义为&#xff1a;以下标i为结尾的nums1和以下标j为结尾的nums2之间的公共最长子数组。 易得&#xff1a;递推公式为dp[i][j] dp[i-1][j-1] 1&#xff1b; 由此可以看出当…

电商项目part05 微服务网关整合OAuth2.0授权中心

微服务网关整合 OAuth2.0 思路分析 网关整合 OAuth2.0 有两种思路&#xff0c;一种是授权服务器生成令牌, 所有请求统一在网关层验证&#xff0c;判断权 限等操作&#xff1b;另一种是由各资源服务处理&#xff0c;网关只做请求转发。 比较常用的是第一种&#xff0c;把API网关…

从零做软件开发项目系列之四——数据库设计

前言 在对软件进行设计的过程中&#xff0c;数据库的设计是一项重要的内容&#xff0c;软件中主要的处理对象就是各类业务数据&#xff0c;通过对业务数据的处理&#xff0c;实现各种功能。我们经常说的&#xff0c;写程序&#xff0c;说到底就是增删改查&#xff0c;而增删改…

IDEA远程开发

IDEA远程开发 前期准备 IDEA的远程开发是在本地去操昨远程服务器上的代码&#xff0c;所以我们先需要准备一台服务器,在此我使用vmware虚拟出ubuntu-20.04.6的Server版本,以便后面演示。 Ubuntu的Java环境配置 JDK8 sudo apt install openjdk-8-jdkmaven sudo apt instal…

NAT的配置实验

一、实验目的 学习如何配置NAT 二、预备知识: Net Address Translation:通过将内部用户的地址转换为1个公用的外部地址&#xff0c;然后再与外部的用户进行通信&#xff0c;从而既节省了IPv4地址&#xff0c;又实现了对内部用户的安全保护 三、实验过程&#xff1a; …

unity动画融合

1、抛砖引玉 在大型复杂的场景中&#xff0c;一定遇到过手在鼓掌&#xff0c;头在摇头&#xff0c;腿又是其他动作的要求&#xff0c;但是这些东西又不能做一起&#xff0c;因为有时候要把某个动画单独使用&#xff0c;这时候就用到了动画融合&#xff0c;利用动画状态机分层机…

taro react/vue h5 中的上传input onchange 值得区别

<inputclassNamebase-input-file-h5typefileacceptimage/*capturecameraonChange{onChangeInput} />1、taro3react 2、taro3vue3

Android12之ABuffer数据处理(三十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

【1267. 统计参与通信的服务器】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff…

docker可视化工具

安装Portainer 官方安装说明&#xff1a;https://www.portainer.io/installation/ [rootubuntu1804 ~]#docker pull portainer/portainer[rootubuntu1804 ~]#docker volume create portainer_data portainer_data [rootubuntu1804 ~]#docker run -d -p 8000:8000 -p 9000:90…

深入理解 Vue Router:构建可靠的前端路由系统

目录 01-什么是前端路由以及路由两种模式实现原理02-路由的基本搭建与嵌套路由模式03-动态路由模式与编程式路由模式04-命名路由与命名视图与路由元信息05-路由传递参数的多种方式及应用场景06-详解route对象与router对象07-路由守卫详解及应用场景 01-什么是前端路由以及路由两…

XShell 使用命令登陆主机

以root&#xff08;管理者&#xff09;身份登录主机 假设&#xff1a; root的ip&#xff1a;111.00.111.000 root的密码&#xff1a;123456 命令格式&#xff1a; ssh root(这里填ip) //接着回车&#xff0c;输入密码即可实操&#xff1a; enter回车后&#xff0c;在弹出的窗口…