关于单源最短路的综合运用
1.概述
图论题中,一般最短路问题会与其他算法相结合来进行考察。
2.最短路与DFS结合
- 题目描述:在一个有n个结点,m条无向边的图中,有x个结点必须访问,求最短路径。
- 题干分析:因为这x个结点必须访问,也可以理解为:最短路径即:这x个结点的1号结点到2号结点的最短路+2号结点到3号结点的最短路+...+n-1号结点到n号结点的最短路。
所以问题转化为了应该如何排列这x个结点,使得1号结点依次经过其余x-1个结点,所经过的路径最短。 - 算法分析:在数据范围小的情况下,可以考虑DFS来对这个x个结点进行排列;如果数据范围较大,则应该使用其他算法。
- 注意点:由于DFS的时间复杂度较高,所以一般需要先用Dijkstra算法对这x个结点间的最短路做预处理。时间复杂度为:O(nnn*log(m))。
- 算法框架:
int main(){
//...
for(int i=1;i<=x;i++){
dijkstra(p[i]);
for(int j=1;j<=x;j++){
ans[i][j]=dist[p[j]]
}
}
//...
dfs();
3.最短路与二分结合
- 题目概述:怎么走,使得这条路径中的第k大的边最小。
- 题干分析:可以通过最短路算法来查找该路径中有多少条边的权重大于k。因为k的取值有二段性,所以可以使用二分查找k值。
- 算法框架:
int main(){
int l=0,r=n+1;
while(l<r){
int mid=(l+r)/2;
if(dijkstra(mid)<=k){ //即把常规二分的check函数变成了求最短路算法
r=mid
}
else{
l=mid-1;
}
}
}
4.拓扑排序+DFS+最短路
- 题目描述:有多块区域它们通过道路(>0)相连,区域间通过航线(可正可负,单向)相连。求最短路。
- 算法分析:
- 因为存在负权边,所以不能直接使用Dijkstra算法求最短路;同时如果数据范围较大,则SPFA算法也不可以使用。
- 首先考虑区域间的道路,因为它们>0,所以可以使用Dijkstra算法。
- 其次考虑航线,因为是单向的,所以可以考虑使用拓扑排序,根据拓扑序来计算各个区域间的最短路。
- 算法框架:
int main(){
for(int i=1;i<=n;i++){
if(!id[I]){
dfs(); //判断哪些区域连通
}
}
//输入点+入度
tosort(); //拓扑排序
}