该算法常用于求单源最短路径,访问给定的s(源点)到其他位置的最短距离。
基本思路
void Dijkstra(G,d[],s)//G为图,一般设成全局变量,d数组存放源点到各点的最短路径长度,s为起点。
{
初始化;
for(循环n次)
{u=使d[u]最小还未被访问的顶点的标号;
记u为已被访问
for(从u出发能被访问的所有顶点v)
{
if(v未被访问&&以u为中介的使s到v的d[v]更优)
{优化d[v];}
}
}
}
邻接矩阵版,适用于顶点数不超过1000;总时间复杂度为O(V^2),V为顶点数
const int MAXV=1000;//最大顶点数
const int INF=1000000000;//
int n,G[MAXV][MAXV];//n为顶点数;
int d[MAXV];//起点到达各点的最短路径长度;
bool vis[MAXV]={false};//标记数组,是否已访问;
void Dijkstra(int s)//s为起点
{
fill(d,d+MAXV,INF);//整个数组赋值为INF,即不连通;(初始化)
d[s]=0;//起点s到自身的距离为0;
for(int i=0;i<n;i++)
{
int u=-1,MIN=INF;//u使d[u]最小,MIN存放该最小的d[u];
for(int j=0;j<n;j++)//找未访问的顶点中d[]最小的
{
if(vis[j]==false&&d[j]<MIN)
{
u=j;MIN=d[j];
}
}
//找不到比INF更小的d[u],说明剩下的顶点不连通
if(u==-1)return;
vis[u]=true;//标记u为已访问;
for(int v=0;v<n;v++)
{//如果v未访问&&u能到达v&&以u为中介点可以使d[v]更优
if(vis[v]==false&&G[u][v]!=INF&&d[u]+G[u][v]<d[v])
d[v]=d[u]+G[u][v];//优化d[v];
}
}
}
邻接表版,时间复杂度为O(V^2+E),E为枚举v次数的时间
const int MAXV=1000;//最大顶点数
const int INF=1000000000;//
int n,G[MAXV][MAXV];//n为顶点数;
int d[MAXV];//起点到达各点的最短路径长度;
bool vis[MAXV]={false};//标记数组,是否已访问;
struct Node{
int v,dis;//边的目标顶点,dis为边权
};
vector<Node>Adj[MAXV];
void Dijkstra(int s)//s为起点
{
fill(d,d+MAXV,INF);//整个数组赋值为INF,即不连通;(初始化)
d[s]=0;//起点s到自身的距离为0;
for(int i=0;i<n;i++)
{
int u=-1,MIN=INF;//u使d[u]最小,MIN存放该最小的d[u];
for(int j=0;j<n;j++)//找未访问的顶点中d[]最小的
{
if(vis[j]==false&&d[j]<MIN)
{
u=j;MIN=d[j];
}
}
//找不到比INF更小的d[u],说明剩下的顶点不连通
if(u==-1)return;
vis[u]=true;//标记u为已访问;
//只有以下和邻接矩阵不同
for(int j=0;j<Adj[u].size();j++)
{//如果v未访问&&u能到达v&&以u为中介点可以使d[v]更优
if(vis[v]==false&&d[u]+Adj[u][j].dis<d[v])
d[v]=d[u]+Adj[u][j].dis;//优化d[v];
}
}
}
可以直接使用优先队列priority_queue,时间复杂度为O(VlogV+E);
Dijkstra算法只能用于边权非负的情况,如果有负数,最好用SPFA