1111. Online Map (30)[dijkstra算法]

2023-12-02 15:58
文章标签 算法 map 30 online dijkstra 1111

本文主要是介绍1111. Online Map (30)[dijkstra算法],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 原题: https://www.patest.cn/contests/pat-a-practise/1111

2. 思路:

题意:
给定图含有时间及距离。
求单源最短路径。
要求:
1. 输出距离最短路径。存在多条时,选择时间最短的。
2. 输出时间最短的路径。存在多条时,选择结点数最少的。


思路:
题意不难。显然dijkstra算法。
对距离和时间分别dijkstra就可以了。
我写了两个dijkstra函数(代码比较长,好在第二个复制改了下)。
也可以写一个,然后调用不同参数,这样代码少。都可以。
已AC。

3. 源码:

#include<iostream>
#include<vector>
using namespace std;const int Max = 500;//最大结点数
const int INF = 0x7FFFFFFF;//无穷大
int N, M, s, d;//分别为结点数, 路径数, 起点,目的地。
int len[Max][Max], dtime[Max][Max];//分别为路径长度的图和时间花费的图
int collected[Max] = { 0 };//记录是否已经遍历
int path[Max];//记录路径
int dist[Max];//记录起点到某点的花费int findMin();//找出未收录的最小长度
void dijkstra_len();//对路径长度图进行dijkstra
void dijkstra_time();//对时间花费图进行dijkstra
void generatePath(vector<int> &v, int index);//生成最短路径
void print(vector<int> &v);//输出路径int main(void)
{//freopen("in.txt", "r", stdin);scanf("%d %d", &N, &M);for (int i = 0; i < N; i++)//图进行初始化{for (int j = 0; j < N; j++)len[i][j] = dtime[i][j] = INF;}for (int i = 0; i < M; i++)//读入数据{int start, end, flag, t_len, t_time;scanf("%d %d %d %d %d", &start, &end, &flag, &t_len, &t_time);if (flag == 0)//说明是双向{len[start][end] = len[end][start] = t_len;dtime[start][end] = dtime[end][start] = t_time;}else//单向路径{len[start][end] = t_len;dtime[start][end] = t_time;}}scanf("%d %d", &s, &d);//起点, 终点dijkstra_len();//对路径长度图进行dijkstravector<int> timepath, lenpath;//分别存储两个输出的路径int lenWgt = dist[d];//距离总开销generatePath(lenpath, d);//生成路径dijkstra_time();int timeWgt = dist[d];generatePath(timepath, d);if (timepath == lenpath)//相同路径,输出一个即可{printf("Distance = %d; Time = %d: ", lenWgt, timeWgt);print(timepath);}else{printf("Distance = %d: ", lenWgt);print(lenpath);printf("Time = %d: ", timeWgt);print(timepath);}return 0;
}void dijkstra_len()//对路径长度图进行dijkstra
{int total[Max];//记录到达某点时的总时间for (int i = 0; i < N; i++)//初始化{total[i] = dtime[s][i];dist[i] = len[s][i];path[i] = -1;//这里的值是存储父结点collected[i] = 0;}dist[s] = 0;total[s] = 0;collected[s] = 1;while (1)//经典算法{int v = findMin();if (v == -1)break;collected[v] = 1;for (int w = 0; w < N; w++){if (collected[w] == 0 && len[v][w] < INF){if ((dist[v] + len[v][w]) < dist[w]){dist[w] = dist[v] + len[v][w];path[w] = v;total[w] = total[v] + dtime[v][w];}else if ((dist[v] + len[v][w]) == dist[w]){if ((total[v] + dtime[v][w]) < total[w]){path[w] = v;total[w] = total[v] + dtime[v][w];}}}}}return;
}void dijkstra_time()//对时间花费图进行dijkstra
{int cnt[Max] = { 0 };//记录到达某点的总结点数for (int i = 0; i < N; i++){dist[i] = dtime[s][i];path[i] = -1;collected[i] = 0;}dist[s] = 0;collected[s] = 1;while (1){int v = findMin();if (v == -1)break;collected[v] = 1;for (int w = 0; w < N; w++){if (collected[w] == 0 && dtime[v][w] < INF){if ((dist[v] + dtime[v][w]) < dist[w]){dist[w] = dist[v] + dtime[v][w];path[w] = v;cnt[w] = cnt[v] + 1;}else if ((dist[v] + dtime[v][w]) == dist[w]){if ((cnt[v] + 1) < cnt[w]){path[w] = v;cnt[w] = cnt[v] + 1;}}}}}return;
}int findMin()//找出未收录的最小长度
{int min_val = INF;int min_id = -1;for (int i = 0; i < N; i++){if (collected[i] == 0 && dist[i] < min_val){min_val = dist[i];min_id = i;}}return min_id;//-1表dijkstra算法结束
}void generatePath(vector<int> &v, int index)//递归把结点压入容器
{if (index == -1){v.push_back(s);return;}generatePath(v, path[index]);v.push_back(index);return;
}void print(vector<int> &v)//输出路径
{for (int i = 0; i < v.size(); i++){if (i != 0)printf(" -> ");printf("%d", v[i]);}printf("\n");
}


这篇关于1111. Online Map (30)[dijkstra算法]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445932

相关文章

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

JavaScript中的Map用法完全指南

《JavaScript中的Map用法完全指南》:本文主要介绍JavaScript中Map用法的相关资料,通过实例讲解了Map的创建、常用方法和迭代方式,还探讨了Map与对象的区别,并通过一个例子展... 目录引言1. 创建 Map2. Map 和对象的对比3. Map 的常用方法3.1 set(key, v

Golang中map缩容的实现

《Golang中map缩容的实现》本文主要介绍了Go语言中map的扩缩容机制,包括grow和hashGrow方法的处理,具有一定的参考价值,感兴趣的可以了解一下... 目录基本分析带来的隐患为什么不支持缩容基本分析在 Go 底层源码 src/runtime/map.go 中,扩缩容的处理方法是 grow

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

shell脚本自动删除30天以前的文件(最新推荐)

《shell脚本自动删除30天以前的文件(最新推荐)》该文章介绍了如何使用Shell脚本自动删除指定目录下30天以前的文件,并通过crontab设置定时任务,此外,还提供了如何使用Shell脚本删除E... 目录shell脚本自动删除30天以前的文件linux按照日期定时删除elasticsearch索引s