观察:对于每个节点,我们可以重用它到目的地的最小路径,因此我们不必重新计算它(dp)。另外,当我们发现一个循环时,我们检查它是否为负。如果不是,它将不会影响我们的最终答案,并且我们可以说它与目的地没有连接(无论它是否连接)。
伪代码:
- 给定源节点u和目标节点v - 初始化整数dp数组,存储相对于源节点到目标节点的最小距离。dp[v] = 0,其他一切都是无限的。 - 初始化布尔型onPath数组,表示当前节点是否在我们考虑的路径上。 - 初始化布尔型visited数组,跟踪当前路径是否已经完成(最初全部为假)。 - 初始化int tentative数组,存储节点的试探值。 (tentative[u] = 0) - 返回function(u)。
伪代码:
- 给定源节点u和目标节点v - 初始化整数dp数组,存储相对于源节点到目标节点的最小距离。dp[v] = 0,其他一切都是无限的。 - 初始化布尔型onPath数组,表示当前节点是否在我们考虑的路径上。 - 初始化布尔型visited数组,跟踪当前路径是否已经完成(最初全部为假)。 - 初始化int tentative数组,存储节点的试探值。 (tentative[u] = 0) - 返回function(u)。
int function(int node){
onPath[node] = true;
for each connection u of node{
if(onPath[u]){ //we've found a cycle
if(cost to u + tentative[node] > tentative[u]) //report negative cycle
continue; //safely ignore
}
if(visited[u]){
dp[node] = min(dp[node], dp[u]); //dp already calculated
}else{
tentative[u] = tentative[node] + cost to u
dp[node] = min(function(u), dp[node])
}
visited[node] = true;
onPath[node] = false;
return dp[node];
}
我知道这个算法不能覆盖目的地是负环的情况,但除此之外,算法还有什么问题吗? 如果没有问题,它叫什么名字?