用于解决带权图(稠密图->邻接矩阵)中任意两点之间的最短路径 时间复杂度O(n^3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int gcd(int x,int y) {
return y ? gcd(y,x%y) : x;
}
ll mp[2022][2022];
int main() {
int n = 2021;
// vector<vector<PPI>> g(n+1);
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(i == j) mp[i][j] = 0;
else if(abs(i-j) <= 21) mp[i][j] = i/gcd(i,j)*j;
else mp[i][j] = INT_MAX;
// g[i].push_back(PPI(i/gcd(i,j)*j,j));
// g[j].push_back(PPI(i/gcd(i,j)*j,i));
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {
mp[i][j] = min(mp[i][j],mp[i][k]+mp[k][j]);
}
cout<<mp[1][2021]<<endl;
return 0;
}
注意是要非负权图
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e6;
int cost[MAX][MAX]; // 表示e=(u,v)的边权
int d[MAX]; // 从顶点s出发的最短距离
bool used[MAX]; // 表示已经用过的点
int V; // 顶点数
void dijkstra(int s) {
d[s] = 0;
fill(d,d+V,INT_MAX);
while(1) {
int v = -1;
for(int u=0;u<V;u++)
if(!used[u] && (v==-1 || d[u] < d[v]))
v = u; // 遍历所有B集合中的点,从而找到离A集合最近的点
if(v == -1) break; // 如果没有找到,说明已经遍历完成了
used[v] = true;
for(int u=0;u<V;u++)
d[u] = min(d[u],d[v]+cost[u][v]);
}
}
int main() {
return 0;
}
堆优化
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e5;
struct edge {
int w,v;
};
struct node {
int id; // B与A最近的点的编号
ll di; // 记录最短边权
bool operator > (const node& a) const {return di > a.di;}
};
vector<edge> e[MAX];
int vis[MAX];
int d[MAX];
int n;
priority_queue<node,vector<node>,greater<node>>q;
void dijstra(int s) {
fill(d,d+n,INT_MAX);
d[s] = 0;
q.push({s,0});
while(!q.empty()) {
int id = q.top().id;
ll di = q.top().di;
q.pop();
if(vis[id]) continue;
vis[id] = 1;
for(auto ed : e[id]) {
int v = ed.v,w = ed.w;
if(d[v] > d[id] + w) {
d[v] = d[id] + w;
q.push({d[v],v});
}
}
}
}
int main() {
}