最短路
分类
单源最短路:从一个点到其他所有点的最短路
算法:
多源最短路:从所有点到另外点的最短路
算法:
Floyd算法
时间复杂度:
适用范围:
思想
类似于
寻找
个点
,判断是否存在一个中间点
,使得
的距离小于
的距离
由此得到方程式
核心代码
memset(d,127,sizeof(d));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(i==j||i==k||j==k) continue;
d[i][j]=min(d[i][k]+d[j][k],d[i][j]);
}
}
}
Dijkstra算法初步
时间复杂度:
(可以优化到
)适用范围
适用范围:
到
思想
考虑在一个无负权边的图上(实际上是没有负环),如果一个点在一些点中离起点的距离最近,那么其他点必定无法更新起点到它的最短路。
我们先将距离赋一个极大值,然后用起点更新其他点的距离,此时标记起点。
然后找到剩余点中距离最小的点,标记它,用它来更新剩下的点。
被标记的点不被选择,不被更新,当所有点被标记后,输出每个点到起点的距离,即为最短路。
Example
以上图为例:
首先,
,其余均为极大值,所以用
来更新,标记点
此时
最小,标记点
此时
最小,标记点
此时
…
核心代码
memset(vis,false,sizeof(vis));
memset(d,127,sizeof(d));
for(int i=1;i<=n;i++){
int minn=2147483647,num;
for(int j=1;j<=n;j++){
if(!vis[j]&&d[j]<minn){
minn=d[j];
num=j;
}
}
vis[num]=true;
for(int e=first[num];e;e=nxt[e]){
int v=to[e];
if(d[v]>d[num]+w[e])
d[v]=d[num]+w[e];
}
}