• 【算法】最短路


    Floyd算法

    计算含负权的图上的多源最短路,原理是动态规划。

    (D_{i,j,k})为从(i)(j)的只以((1...k))集合中的结点为中间结点的最短路的长度。

    1.若最短路经过点(k),则(D_{i,j,k}=D_{i,k,k-1}+D_{k,j,k-1})

    2.若最短路不经过点(k),则(D_{i,j,k}=D_{i,j,k-1})

    因此,(D_{i,j,k}=min(D_{i,j,k-1},D_{i,k,k-1}+D_{k,j,k-1}))

    (以上摘自 Floyd-Warshall算法 - 维基百科

    也就是说,对于任意两个需要求最短路的结点(i,j),我们初始化(D[i][j])为结点(i)直接连接到结点(j)的边的长度(如果不存在这条边,则初始化为(INF)。注意,(INF)取得过大可能导致在加法计算中溢出,建议将(INF)取为"只比最大边权的(m)倍((m)为图的总边数)大一点点"的值)。

    当然为了省事,除了(D[i][i])以外,全部初始化为(INF)也行。

    然后遍历(i,j)之间的中间结点(k),在“经过(k)”与"不经过(k)“两种状态之间取路径更短的。状态的转移由动态规划完成。

    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
    			D[i][j] = (i == j ? 0 : INF);
    		}
    	}
    	for (int k = 0; k < n; k++)
    		for (int i = 0; i < n; i++)
    			for (int j = 0; j < n; j++)
    				D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
    

    当我们不关心任意两点间的长度,而只关心两点间是否存在通路时,只需要将预处理部分做些改动,用1和0表示“连通”与“不连通”,将上述代码中D[i][j] = min(D[i][j], D[i][k] + D[k][j])改为D[i][j]=D[i][j]||(D[i][k]&&D[k][j])即可。此时就是在求有向图的传递闭包了。

  • 相关阅读:
    英语老师不想让你知道的一些网站分享
    最近三周开发的桌面应用系统
    UML技术沙龙PPT
    Pandas时间处理的一些小方法
    合并函数总结
    开博宣言
    DBGrid中增加一列CHECKBOX
    关于Delphi的Hint
    操作EXCEL
    关于FastReport
  • 原文地址:https://www.cnblogs.com/streamazure/p/12919388.html
Copyright © 2020-2023  润新知