Dijkstra通过邻接矩阵和邻接表实现有很多版本,其中邻接矩阵实现时间复杂度为:O(n^2),邻接表为:O( V^2+E),最简洁的方法是使用优先队列实现,用邻接表实现时间复杂度为:O(VlogV+E)。
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct g {
int x;
int cost;
friend bool operator < (g a,g b) {
return a.cost>b.cost;
}
};
const int inf=100000;
bool visit[100]= {false};//是否访问
bool visit1[100]= {false};//判断是否入队
int d[100];
int n;
vector<g>v[100];
void Dijkstra_1(int s) {
fill(d,d+100,inf);
d[s]=0;
for(int i = 0; i < n; i++) {
int u=-1,Min=inf;
for(int j = 0; j < n; j++) {
if(visit[j]==false&&Min>d[j]) {
u=j;
Min=d[j];
}
}
if(u==-1)
return ;
visit[u]=true;
for(int i = 0; i < v[u].size(); i++) {
int w=v[u][i].x;
int cost=v[u][i].cost;
if(visit[w]==false&&d[u]+cost<d[w]) {
d[w]=d[u]+cost;
}
}
}
}
void Dijkstra_2(int s) {//优先队列实现
fill(d,d+100,inf);
d[s]=0;
priority_queue<g>q;
g G;
G.x=s;
G.cost=0;
q.push(G);
int count=1;
visit1[s]=true;
while(count<n) {
count++;
g f=q.top();
q.pop();
visit[f.x]=true;//标记访问,确保入队的都是当前未访问的
for(int i = 0; i < v[f.x].size(); i++) {
int u=v[f.x][i].x;
int cost=v[f.x][i].cost;
if(visit[u]==false&&d[f.x]+cost<d[u]) {
d[u]=d[f.x]+cost;
if(visit1[u]==false) {//避免重复入队
g m;
m.x=u;
m.cost=v[f.x][i].cost;
q.push(m);
visit1[u]=true;
}
}
}
}
}
int main() {
int m;
cin>>n>>m;
for(int i = 0; i < m; i++) {
int a,b,cost;
cin>>a>>b>>cost;
g G;
G.x=b;
G.cost=cost;
v[a].push_back(G);
G.x=a;
v[b].push_back(G);
}
Dijkstra_2(0);
for(int i = 0; i < n; i++)
cout<<d[i]<<" ";
return 0;
}