我们来观察一下单元最短路径1的代码:
我们发现,每一次我们都需要遍历所有的边,无论是否已经使用过,但其实,我们可以从上一次确定过的最短距离的点出发再去寻找,这样可以继续缩短查找的时间。
好的,因此我们可以继续简化算法,在求解最短路径最常用的算法就是:dijkstra算法
这里写目录标题
准备:
这个算法需要一个标记数组来表示点是否已经使用过,
int cost[MAXN][MAXN];
int d[MAXN];
bool used[MAXN];
int V,E;
初始化:
void initial()
{
fill(d,d+V,INF);
fill(used,used+V,false);
d[s]=0;
}
实现:
//我们不知道需要进行几次循环
while(true)
{
int v =-1;
for (int u = 0; u < V; u++)
{
if(!used[u] && (v=-1 || d[u] < d[v]) v = u;
//u没有使用过,一开始的时候起点也是未使用过的
}
if(v==-1) break;//所有使用过的点都已经找完了
used[v]=true;
for (int u = 0; u < V; u++)
{
d[u]=min(d[u],d[v]+cost[v][u]);
}
}
这个算法复杂度是O(V^2),如果使用邻接表的存储方式复杂度是O(E),因为每一条边只需要访问一次。但是每一次枚举顶点的时候, 需要枚举所有的顶点来查找下一个顶点,复杂度依然是O(V^2)