小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。
小蓝的图由2021 个结点组成,依次编号1 至2021。
对于两个不同的结点a, b,如果a 和b 的差的绝对值大于21,则两个结点之间没有边相连;
如果a 和b 的差的绝对值小于等于21,则两个点之间有一条长度为a 和b 的最小公倍数的无向边相连。
例如:结点1 和结点23 之间没有边相连;结点3 和结点24 之间有一条无向边,长度为24;
结点15 和结点25 之间有一条无向边,长度为75。
请计算,结点1 和结点2021 之间的最短路径长度是多少。
提示:建议使用计算机编程解决问题。
djistra算法可以跑,floyd比较好记,所以两者都可以做
#include <iostream>
#include <bits/stdc++.h>
#define MAX 100000000
using namespace std;
int G[2022][2022]={0};
void inin(){
for(int i=1;i<2022;i++){
for(int j=1;j<2022;j++){
if(i==j) G[i][j]=MAX;
else if(abs(i-j)<=21){
G[i][j]=(i*j)/__gcd(i,j);
}
else{
G[i][j]=MAX;
}
}
}
}
bool vis[2022]={false};
int dis[2022]={MAX};
void dijistra(){
dis[1]=0;
for(int i=1;i<2022;i++){
int k=-1;
int min=MAX;
for(int j=1;j<2022;j++){
if(!vis[j]&&dis[j]<min){
min=dis[j];
k=j;
}
}
if(k==-1)break;
vis[k]=1;
for(int z=1;z<2022;z++){
if(!vis[z] && dis[k]+G[k][z]<dis[z]){
dis[z]=dis[k]+G[k][z];
}
}
}
}
void floyd(){
for(int k=1;k<2022;k++){
for(int v=1;v<2022;v++){
for(int w=1;w<2022;w++){
if(G[v][w]>(G[v][k]+G[k][w])){
G[v][w]=G[v][k]+G[k][w];
}
}
}
}
}
int main() {
inin();
//dijistra();
floyd();
cout<<G[1][2021];
//cout<<dis[2];
return 0;
}