Bellman ford邻接矩阵的单源最短路径未检测到负周期

问题描述

我尝试为邻接矩阵实现Bellman ford单源最短路径,但是它没有检测到负周期中的一个顶点

相同的算法适用于边缘列表,但在邻接矩阵中产生错误

图形如下所示:

enter image description here

我的代码

#include <iostream>
#include <climits>
#include <vector>
using namespace std;

#define INF INT_MAX
#define NINF INT_MIN

void shortestpath(int src,vector<vector<int>> &matrix){
    int N = matrix.size();
    vector<int> dist(N,INF);
    vector<int> prev(N,0);

    dist[src] = 0;
    for(int k = 0; k < N-1; k++){
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(dist[i] != INF && matrix[i][j] && dist[j] > (dist[i] + matrix[i][j]) ){
                    dist[j] = dist[i] + matrix[i][j];
                    prev[j] = i;
                }
            }
        }
    }

    // for(int i = 0; i < N; i++)
    //     if(i != src)
    //         cout << src << " - " << i << "\t" << dist[i] << endl;
    // cout << "\n\n";

    // to check if -ve cycles exist or not
    for(int k = 0; k < N-1; k++){
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(matrix[i][j] && dist[j] > (dist[i] + matrix[i][j]) ){
                    dist[j] = NINF;
                    prev[j] = -1;
                }
            }
        }
    }

    for(int i = 0; i < N; i++)
        if(i != src)
            cout << src << " - " << i << "\t" << dist[i] << endl;
    return ;
}

// Driver function
int main(){
    int V = 8;
    vector<vector<int>> matrix(V,vector<int>(V,0));
    matrix[0][1] = 1;
    matrix[1][2] = 1;
    matrix[2][4] = 1;
    matrix[4][3] = -3;
    matrix[3][2] = 1;
    matrix[1][5] = 4;
    matrix[1][6] = 4;
    matrix[5][6] = 5;
    matrix[6][7] = 4;
    matrix[5][7] = 3;

    shortestpath(0,matrix);

    return 0;
}
 

输出

0 -> 1   =   1
0 -> 2   =  -2147483648
0 -> 3   =  -3
0 -> 4   =  -2147483648
0 -> 5   =  5
0 -> 6   =  5
0 -> 7   =  8

在2-> 4-> 3处有一个-ve周期,但是我的代码仅检测到2和4

解决方法

在第二个循环中,如果dist[i] + matrix[i][j]已设置为dist[i]并且INT_MIN为负,则matrix[i][j]可能会表现出整数溢出的未指定行为。在实践中,总和会绕到一个大的正数,然后条件dist[j] > (dist[i] + matrix[i][j])不成立,并且dist[j]不会更新。