关于单源最短路的综合运用

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();       //拓扑排序
}
5.DP+最短路
posted @ 2021-03-11 19:03  z_thorn  阅读(66)  评论(0编辑  收藏  举报