试题 算法训练 最短路
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
解题思路:
题目中写到某些边权可能为负,但保证没有负环,Dijkstra算法要求边的权值非负,因此不能使用;题目中n的最大值为20000,但Floyd-Warshall算法的时间复杂度为O(N3),空间复杂度为O(N2),一定会超时(n小于500时再考虑Floyd-Warshall算法)。想到Bellman-ford算法适用于单源最短路径,图中边的权重可为负数即负权边,但不可以出现负权环,因此本题使用Bellman-ford算法。
这里还需要解释一下负边权和负权环的概念:
负权边:权重为负数的边。
负权环:源点到源点的一个环,环上权重和为负数。
算法描述:
1.设立五个一维数组:存放从第1个节点到第i个节点的最短路径dist[20005],临时数组tmp[20005],边起点数组u[200009],边终点数组v[200009],边权值数组len[200009]。
int u[200009],v[200009],len[200009];
int dist[20005],tmp[20005];
2.遍历所有的边,来改变每个源点的最短距离(核心思想)。
for(int i=1;i<=n;i++){//flag = 0;//for(int j=1;j<=n;j++)//{// tmp[j] = dist[j];//}for(int k=1;k<=m;k++){if(dist[v[k]]>dist[u[k]]+len[k]){dist[v[k]] = dist[u[k]]+len[k];}}}
考虑到时间复杂度为O(n2),当n取值偏大时可能会出现超时的情况,因此需要用一个临时数组tmp来储存每轮结束后的最短路径数,用一个标记flag来监控该数据是否发生改变,如果出现变化则继续,反之则退出循环,表示已经找到全部的最短路径。
for(int h=1;h<=n;h++)
{if(tmp[h]!=dist[h]){flag = 1;break;}
}
if(flag==0)
{break;
}
代码:
#include<iostream>
#include<cstring>
using namespace std;
int u[200009],v[200009],len[200009];
int dist[20005],tmp[20005]; //临时数组
int main()
{int n,m,flag; //标记 cin>>n>>m;for(int i=1;i<=m;i++){cin>>u[i]>>v[i]>>len[i];}memset(dist,1000000,sizeof dist); //所有路径初始化为最大值 dist[1] = 0; //本身距离为0 for(int i=1;i<=n;i++){flag = 0;for(int j=1;j<=n;j++){tmp[j] = dist[j];}for(int k=1;k<=m;k++){if(dist[v[k]]>dist[u[k]]+len[k]){dist[v[k]] = dist[u[k]]+len[k]; //计算最短路径 }}for(int h=1;h<=n;h++){if(tmp[h]!=dist[h]) //只要发生改变就退出 ,说明仍然存在还未找出的最短路径 {flag = 1;break;}}if(flag==0) //说明找到了所有的最短路径,没有必要再进行下去,结束循环 {break;}}for(int i=2;i<=n;i++){cout<<dist[i]<<endl; //输出1号点到i+1号点的最短路径 }return 0;}
试题 算法训练 最短路相关推荐
- 试题 算法训练 逗志芃的暴走
试题 算法训练 逗志芃的暴走 复习累了随便刷了道题,但没想到的是这道dfs有点坑... 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 逗志芃是有妹子的现充,但是有时候妹子就是烦恼. ...
- 蓝桥杯试题 算法训练 Have You Ever Heard About the Word?
试题 算法训练 Have You Ever Heard About the Word? 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 一个字符串的子串是该字符串的一段连续子序列,如 ...
- C++试题 算法训练 相邻数对、画图
试题 算法训练 相邻数对 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1. 输入格式 输入的第一行包含一个整数n,表示 ...
- 蓝桥杯试题 算法训练 印章
试题 算法训练 印章 C/C++ 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 共有n种图案的印章,每种图案的出现概率相同.小A买了m张印章,求小A集齐n种印章的概率. 输入格式 ...
- 试题 算法训练 翻转旋转变换
试题 算法训练 翻转旋转变换 资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 现在有一张n行m列的由" ...
- 试题 算法训练 盾神与离散老师2
试题 算法训练 盾神与离散老师2 资源限制 **时间限制:**1.0s 内存限制:256.0MB 问题描述 有一天,盾神觉得自己离散课快要挂了,于是亲自找到离散老师WH,请教如何才能不挂科.WH老师说 ...
- 试题 算法训练 预测身高
试题 算法训练 预测身高 Lan 2020-03-13 19:04 54 人阅读 0 条评论 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述: 生理卫生老师在课堂上娓 ...
- 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解
题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...
- 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解 - 未完善
题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...
最新文章
- 如何修改配置以修复ThinkPad 小红帽滚轮失效?
- 视频直播营销时代已来,企业该如何把握这波红利?
- 十分钟上线-基于函数计算开发 Restful web api asp.net core web app
- c语言 枚举定义变量,C语言之枚举的定义以及测试
- Spring @Import 注解使用详解
- jexboss工具 -- JBOSS未授权访问漏洞利用
- 项目总结:华南师范大学校园开发教育android客户端总结
- hive sql 优化
- ubuntu 下可以尝试还不错的屏幕截图工具: flameshot
- JavaScript强化教程——数组的基本处理函数
- svn 同步 linux,linux SVN 中 配置钩子 实现 线上项目同步
- Oracle中可以代替like进行模糊查询的方法instr(更高效)
- 电脑摄像头测试软件在线,AMCap 摄像头测试软件使用说明
- 关闭445端口操作手册
- Arduino蜂鸣器唱曲天空之城
- 《SolidWorks 2014中文版机械设计从入门到精通》——第 1 章 认识SolidWorks 1.1 SolidWorks概述...
- 百人计划 美术 1.1 美术理论基础
- 堆排序中非叶子节点的位置怎么算
- 【2021.03.19】长调用与短调用
- 固化EOS智能合约,监管升级权限,净化EOS DAPP生态