
cpp
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n,m,u,v,w;
cin>>n>>m;
vector<vector<vector<int>>> grid(n+1,vector<vector<int>>(n+1,vector<int>(n+1,10001)));
while(m--){
cin>>u>>v>>w;
grid[u][v][0]=w;
grid[v][u][0]=w;
}
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
grid[i][j][k]=min(grid[i][k][k-1]+grid[k][j][k-1],grid[i][j][k-1]);
}
}
}
int num,start,end;
cin>>num;
while(num--){
cin>>start>>end;
if(grid[start][end][n]==10001){
cout<<-1<<endl;
}
else{
cout<<grid[start][end][n]<<endl;
}
}
return 0;
}
之前我们涉及的迪杰斯特拉算法和贝尔曼福德算法都是针对单源最短路径的,而当问题来到多源的最短路径时这两种算法就不适用了。针对多源最短路径问题,我们一般用floyd算法或者A星算法。

cpp
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int moves[1001][1001];
int b1,b2;
const vector<pair<int,int>> dirs={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{-1,2},{1,-2},{1,2}};
struct Knight{
int x,y;
int g,h,f;
bool operator < (const Knight& k)const{
return k.f<f;
}
};
priority_queue<Knight> pq;
int OlaDis(const Knight& k){
return (k.x-b1)*(k.x-b1)+(k.y-b2)*(k.y-b2);
}
void astar(const Knight& k){
Knight cur,nex;
pq.push(k);
while(!pq.empty()){
cur=pq.top();
pq.pop();
if(cur.x==b1&&cur.y==b2)break;
for(auto [dx,dy]:dirs){
nex.x=cur.x+dx;
nex.y=cur.y+dy;
if(nex.x<1||nex.x>1000||nex.y<1||nex.y>1000)continue;
if(!moves[nex.x][nex.y]){
moves[nex.x][nex.y]=moves[cur.x][cur.y]+1;
nex.g=cur.g+5;
nex.h=OlaDis(nex);
nex.f=nex.g+nex.h;
pq.push(nex);
}
}
}
}
int main(){
int n;
cin>>n;
int a1,a2;
while(n--){
cin>>a1>>a2>>b1>>b2;
memset(moves,0,sizeof(moves));
Knight start;
start.x=a1;
start.y=a2;
start.g=0;
start.h=OlaDis(start);
start.f=start.g+start.h;
astar(start);
while(!pq.empty())pq.pop();
cout<<moves[b1][b2]<<endl;
}
return 0;
}
这个就是A星算法了。