关于最小生成树和最短路径的几个有趣问题

  1. Q:不连通的树不含最小生成树,为什么?
    A:这很容易证明,如果含有最小生成树,图必定是连通的;反之,如果图是连通的,总可以利用prim算法或kruskal算法或者破圈法得到最小生成树;如果图不连通,prim算法和kruskal算法也会固执地给出起点所在连通分支的最小生成树。

  2. Q:将Dijkstra算法求得的起点到其余点的路径及路径上的点拼成一个新的图,该图是不是树?
    A:是。利用反证法,得到的图一定是连通图,假设不是树,则肯定存在回路,并且起点在这条回路上,对于该回路上其余点来说,就找到了两条从起点到该点的最短路径,但是Dijkstra算法至多能找出一条,矛盾。所以假设错误,得到的连通图是树。

  3. Q:那这个树是不是最小生成树?
    A:很有可能不是。拿Dijkstra算法和prim算法进行比较,虽然两者很相似——都是通过添加顶点来实现的,但是添加顶点的条件不同,Dijkstra算法是找未加入点中距离起点的已知最小距离最小的那个点,而prim算法找的是未加入节点中距离已加入节点的距离最小的那个点,所以,得到的结果很有可能不一样。

  4. Q:同样是利用邻接矩阵求任意两点间的最短路径,调用N(顶点个数)次Dijkstra算法和一次Floyd算法时间复杂度是否相同?实际执行效率是否相同?

    A:时间复杂度是一样的,都是O(N3)O(N^3),但是一次Floyd算法的执行效率更高;原因应该是这样的:Floyd算法是在原有的邻接矩阵的基础上进行了 N 次优化,且每次优化都利用到了前面优化的结果,有效地利用了最新数据;而调用 N 次Dijkstra算法,没有考虑这 N 次之间的联系,所以会有一部分的重复工作,举个例子,假设已经求得 v1 到 v3 的最短路径和 v2 到 v1 的最短路径,现在求 v2 到 v3 的最短路径,如果已知 v1 是该最短路径上的点,那么直接将前面得到的两个最短路径拼接起来即可,无需假装不知道傻傻地求出来;总的来说,Dijkstra算法调用 N 次,每次调用都没用到前面的调用结果,故有一定的重复操作,而Floyd算法的每次更新都是基于最新的更新结果,所以后者的效率更高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章