Dijkstra算法的策略是:
设置集合S存放已被访问的节点, 然后执行n次下面的两个步骤(n为顶点数):
1. 每次从集合V-S中 选择与起点S的最短距离最小的一个顶点(记为u),访问并加入集合S
2. 之后,令顶点u为中介点,优化起点s 与所有人从u到达顶点v的最短距离。
伪代码:
Dijkstra( G, d[], s)
{
初始化:
for(循环n次)
{
u=使d[u]最小的还未被访问的顶点的编号
记u已经被访问 ;
for(从u出发到达所有的顶点v)
{
if( v未被访问&&以u为中介点使s到达顶点v 的最短距离的d[v] 更优)
{
优化d[v];
}
}
}
}
下面看一下邻接矩阵版的核心代码
#include<bits/stdc++.h>
const int maxn=1000;
const int INF=1000000000;
int n,G[maxn][maxn];
int d[maxn];
bool vis[maxn]={false};
void Dijkstra(int s)
{
fill(d,d+maxn,INF);
d[s]=0;
for(int i=0;i<n;i++)
{
int u=-1;MIN=INF;
for(int j=0;j<n;j++)
{
if(vis[j]==false&&d[j]<MIN)
{
u=j;
MIN=d[j];
}
}
if(u==-1) return;
for(int v=0;v<n;v++)
{
if(vis[v]=false&&G[u][v]!=INF&&d[u]+G[u][v]<d[v])
{
d[v]=d[u]+G[u][v];
}
}
}
}
邻接表
#include<bits/stdc++.h>
const int maxn=1000;
const int INF=1000000000;
struct Node
{
int v,dis;
};
vector<Node> Adj[maxn];
int n;
bool vis[maxn]={false};
int d[maxn];
void Dijkstra(int s)
{
fill(d,d+maxn,INF);
d[s]=0;
for(int i=0;i<n;i++)
{
int u=-1,MIN=INF;
for(int j=0;j<n;j++)
{
if(vis[j]==false&&d[j]<MIN)
{
u=j;
MIN=d[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int j=0;j<Adj[u].size();j++)
{
int v=Adj[u][j].v;
if(vis[v]==false &&d[u]+Adj[u][j].dis<d[v])
{
d[v]=d[u]+Adj[u][j].dis;
}
}
}
}