代码运行:
#include<iostream>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
int gcd(int a,int b)
{
return b==0 ? a : gcd(b,a%b);//b==0就把a的值返回,如果不等于0,则调用gcd函数。
}
int a[3000][3000];
typedef pair<int, int> PII;
const int N = 1.5e5 + 10;
int n, m, dis[N];
bool vis[N];
int h[N], ne[N], w[N], e[N], idx;
//链表存储边的关系
void add(int x,int y,int z){
w[++idx] = z, e[idx] = y, ne[idx] = h[x], h[x] = idx;
}
int dijkstra(){
//优先队列存储距离和点,按离源点距离排序,越小越在前面
//源点 x = 1, dis[1] = 0
priority_queue<PII, vector<PII>, greater<PII> > p_q;
p_q.push({0, 1} );
dis[1] = 0;
while(!p_q.empty() ){
auto t = p_q.top();
p_q.pop();
//****如果这个点已经被选取确定遍历过它的边,则跳过****
//否则选取这个点并设置为 true
int d = t.first, u = t.second;
if(vis[u]) continue;
vis[u] = true;
//利用u的边去更新和u有联系的点
for(int i = h[u]; ~i; i = ne[i] ){
int j = e[i];
if(dis[j] > d + w[i]){
dis[j] = d + w[i];
p_q.push({dis[j], j} );
}
}
}
if(dis[n] == 0x3f3f3f3f ) return -1;
return dis[n];
}
int main(){
memset(h, -1, sizeof(h) );
memset(dis, 0x3f, sizeof(dis) );
n=2021;
m=42210;
//cin >> n >> m;
memset(a,0,sizeof(a));
for (int i=1; i<=2020; i++)
{
for (int j=i+1; j<=2021; j++)
{
if (j-i<=21)
{
a[i][j]=1;
}
}
}
for (int i=1; i<=3000; i++)
{
for (int j=1; j<=3000; j++)
{
if (a[i][j]==1)
{
add(i,j,(i*j)/gcd(i,j));
}
}
}
cout<<dijkstra()<<endl;
}