LQ0083 路径Dijkstra算法
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0083 路径Dijkstra算法相关的知识,希望对你有一定的参考价值。
题目来源:蓝桥杯2021初赛 C++ A组D题
题目描述
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。
小蓝的图由2021 个结点组成,依次编号1 至2021。
对于两个不同的结点a, b,如果a 和b 的差的绝对值大于21,则两个结点之间没有边相连;
如果a 和b 的差的绝对值小于等于21,则两个点之间有一条长度为a 和b 的最小公倍数的无向边相连。
例如:结点1 和结点23 之间没有边相连;结点3 和结点24 之间有一条无向边,长度为24;
结点15 和结点25 之间有一条无向边,长度为75。
请计算,结点1 和结点2021 之间的最短路径长度是多少。
提示:建议使用计算机编程解决问题
问题分析
最短路问题,可以用Dijkstra算法或Floyd算法来解决。
后者太慢,需要先算出结果后直接输出结果,是杀鸡用牛刀的解法。
用Dijkstra算法来解决是正解。
AC的C++语言程序(Dijkstra算法)如下:
/* LQ0083 路径 */
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
/* Dijkstra算法
* 复杂度:O(N×N)
* 输入:n 全局变量,图结点数
* g 全局变量,邻接矩阵,g[i][j]表示结点i到j间的边距离
* 输出:dis 全局变量,dis[i]表示结点1到i的最短距离
*/
const int INF = 0x3f3f3f3f;
const int N = 2021;
int dis[N + 1], g[N + 1][N + 1], n, vis[N + 1];
void dijkstra()
memset(dis, INF, sizeof dis);
memset(vis, 0, sizeof vis);
dis[1] = 0;
for(int i = 1; i <= n; i++)
int mark = -1, mindis = INF;
for(int j = 1; j <= n; j++)
if(!vis[j] && dis[j] < mindis)
mindis = dis[j], mark = j;
vis[mark] = 1;
for(int j = 1; j <= n; j++)
if(!vis[j])
dis[j] = min(dis[j], dis[mark] + g[mark][j]);
int main()
n = N;
memset(g, INF, sizeof g);
for(int i = 0; i <= n; i++)
g[i][i] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (abs(i - j) <= 21)
g[i][j] = g[j][i] = i * j / __gcd(i, j);
dijkstra();
cout << dis[n] << endl;
return 0;
AC的C++语言程序(Floyd算法)如下:
/* LQ0083 路径 */
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
/* Floyd-Warshall算法:计算图中任意2点之间的最短距离
* 复杂度:O(N×N×N)
* 输入:n 全局变量,图结点数
* g 全局变量,邻接矩阵,g[i][j]表示结点i到j间的边距离
* 输出:g 全局变量
*/
const int INF = 0x3f3f3f3f;
const int N = 2021;
int g[N +1][N + 1], n;
void floyd()
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
int main()
// memset(g, INF, sizeof g);
// n = N;
// for (int i = 1; i <= n; i++)
// for (int j = 1; j <= n; j++)
// if (abs(i - j) <= 21)
// g[i][j] = g[j][i] = i * j / __gcd(i, j);
// floyd();
// cout << g[1][n] << endl; // 10266837
cout << 10266837 << endl;
return 0;
以上是关于LQ0083 路径Dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章