// LLP-BellmanFord shortest paths. Edge weights may be negative. #include #include #include using Matrix = std::vector>; constexpr int INF = INT_MAX / 2; // half-INF to avoid overflow bool forbidden(int j, const std::vector& d, const std::vector>& pre, const Matrix& w) { for (int i : pre[j]) { if (d[i] != INF && d[i] + w[i][j] < d[j]) return true; } return false; } void advance(std::vector& d, const std::vector>& pre, const Matrix& w, int n) { std::vector nd = d; for (int k = 0; k < n; ++k) { for (int i : pre[k]) { if (d[i] != INF && d[i] + w[i][k] < nd[k]) nd[k] = d[i] + w[i][k]; } } d = nd; } std::vector llpBellmanFord(const std::vector>& pre, const Matrix& w, int n) { std::vector d(n, INF); d[0] = 0; bool changed = true; while (changed) { changed = false; for (int j = 0; j < n; ++j) { if (forbidden(j, d, pre, w)) { advance(d, pre, w, n); changed = true; break; } } } return d; } int main() { int n = 4; std::vector> pre = { {}, {0}, {0, 1}, {2} }; Matrix w(n, std::vector(n, INF)); w[0][1] = 1; w[0][2] = 4; w[1][2] = -3; w[2][3] = 1; auto d = llpBellmanFord(pre, w, n); std::cout << "d ="; for (int x : d) std::cout << ' ' << x; std::cout << '\n'; return 0; }