Skip to content

Conversation

@mikestsa
Copy link

  • Computes shortest paths between all pairs of vertices
  • Supports negative edge weights (no negative cycles)
  • Includes helper functions: addEdge(), getDistance(), hasNegativeCycle()
  • Time complexity: O(V³)

Copilot AI review requested due to automatic review settings December 18, 2025 21:41
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds Floyd-Warshall algorithm implementations to compute all-pairs shortest paths in weighted graphs. However, the PR introduces two nearly identical files (floyd_warshall.cpp and floyd_warshall2.cpp) which appears to be unintentional duplication.

Key Changes:

  • Implementation of Floyd-Warshall algorithm with O(V³) time complexity
  • Helper functions for adding edges, retrieving distances, and detecting negative cycles
  • Interactive program with predefined test cases and user input support

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 21 comments.

File Description
graph/floyd_warshall.cpp Floyd-Warshall implementation using size_t for matrix size variable
graph/floyd_warshall2.cpp Duplicate Floyd-Warshall implementation using int for matrix size variable

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// running predefined tests
tests();

int vertices = int(), edges = int();
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary explicit initialization with default constructor. The expression 'int()' is verbose and can simply be '0' or the variable can be left uninitialized since it's assigned before use. The same applies to the edges variable on this line.

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +187
int u = int(), v = int();
int64_t w = int64_t();
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary explicit initialization with default constructor. The expressions 'int()' and 'int64_t()' are verbose. These variables can be declared without initialization since they are assigned values from user input before use.

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +61
std::vector<std::vector<int64_t>>* adj) {
/// n denotes the number of vertices in graph
size_t n = adj->size();

/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = *adj;
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function accepts a raw pointer to a vector, but a const reference would be more appropriate for this use case. Using a raw pointer suggests optional or ownership semantics, neither of which apply here. Since the function only reads the input matrix, consider changing the parameter to a const reference instead.

Suggested change
std::vector<std::vector<int64_t>>* adj) {
/// n denotes the number of vertices in graph
size_t n = adj->size();
/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = *adj;
const std::vector<std::vector<int64_t>>& adj) {
/// n denotes the number of vertices in graph
size_t n = adj.size();
/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = adj;

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +126
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;

std::vector<std::vector<int64_t>> adj1(4, std::vector<int64_t>(4, INF));
for (int i = 0; i < 4; i++) {
adj1[i][i] = 0;
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated matrix initialization pattern. The pattern of creating a matrix filled with INF and then setting diagonal elements to 0 appears in multiple test cases. Consider extracting this into a helper function to improve maintainability and reduce code duplication.

Suggested change
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;
std::vector<std::vector<int64_t>> adj1(4, std::vector<int64_t>(4, INF));
for (int i = 0; i < 4; i++) {
adj1[i][i] = 0;
}
/** Function to create an adjacency matrix with INF weights and 0 on the diagonal. */
std::vector<std::vector<int64_t>> createAdjMatrix(int n) {
std::vector<std::vector<int64_t>> adj(n, std::vector<int64_t>(n, INF));
for (int i = 0; i < n; i++) {
adj[i][i] = 0;
}
return adj;
}
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;
std::vector<std::vector<int64_t>> adj1 = createAdjMatrix(4);

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +68
for (int k = 0; k < n; k++) {
/// for each source vertex i
for (int i = 0; i < n; i++) {
/// for each destination vertex j
for (int j = 0; j < n; j++) {
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type mismatch between loop variable and container size. The variable 'i' is declared as 'int' but is being compared with 'n' which is 'size_t'. This can cause signed/unsigned comparison warnings. The loop variable should be 'size_t' to match the type of 'n'.

Suggested change
for (int k = 0; k < n; k++) {
/// for each source vertex i
for (int i = 0; i < n; i++) {
/// for each destination vertex j
for (int j = 0; j < n; j++) {
for (size_t k = 0; k < n; k++) {
/// for each source vertex i
for (size_t i = 0; i < n; i++) {
/// for each destination vertex j
for (size_t j = 0; j < n; j++) {

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +61
std::vector<std::vector<int64_t>>* adj) {
/// n denotes the number of vertices in graph
int n = adj->size();

/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = *adj;
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function accepts a raw pointer to a vector, but a const reference would be more appropriate for this use case. Using a raw pointer suggests optional or ownership semantics, neither of which apply here. Since the function only reads the input matrix, consider changing the parameter to a const reference instead.

Suggested change
std::vector<std::vector<int64_t>>* adj) {
/// n denotes the number of vertices in graph
int n = adj->size();
/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = *adj;
const std::vector<std::vector<int64_t>>& adj) {
/// n denotes the number of vertices in graph
int n = adj.size();
/// copy the adjacency matrix to dist
std::vector<std::vector<int64_t>> dist = adj;

Copilot uses AI. Check for mistakes.
Comment on lines +110 to +112
if (dist[s][t] != INF) {
return dist[s][t];
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing bounds validation for vertex indices. The function should validate that 's' and 't' are within valid range (0 to n-1 where n is the matrix size) before accessing the matrix to prevent out-of-bounds access.

Suggested change
if (dist[s][t] != INF) {
return dist[s][t];
}
// Validate indices to prevent out-of-bounds access
if (s < 0 || t < 0) {
return -1;
}
const size_t n = dist.size();
if (n == 0) {
return -1;
}
const size_t rows = n;
const size_t cols = dist[0].size();
const size_t si = static_cast<size_t>(s);
const size_t ti = static_cast<size_t>(t);
if (si >= rows || ti >= cols) {
return -1;
}
if (dist[si][ti] != INF) {
return dist[si][ti];
}

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +114
int64_t getDistance(const std::vector<std::vector<int64_t>>& dist, int s,
int t) {
if (dist[s][t] != INF) {
return dist[s][t];
}
return -1;
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing bounds validation for vertex indices. The function should validate that 's' and 't' are within valid range (0 to n-1 where n is the matrix size) before accessing the matrix to prevent out-of-bounds access.

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +126
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;

std::vector<std::vector<int64_t>> adj1(4, std::vector<int64_t>(4, INF));
for (int i = 0; i < 4; i++) {
adj1[i][i] = 0;
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated matrix initialization pattern. The pattern of creating a matrix filled with INF and then setting diagonal elements to 0 appears in multiple test cases. Consider extracting this into a helper function to improve maintainability and reduce code duplication.

Suggested change
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;
std::vector<std::vector<int64_t>> adj1(4, std::vector<int64_t>(4, INF));
for (int i = 0; i < 4; i++) {
adj1[i][i] = 0;
}
/**
* @brief Helper function to create an n x n matrix initialized with INF
* and 0 on the diagonal.
*
* @param n number of vertices (matrix dimension)
* @return initialized adjacency matrix
*/
static std::vector<std::vector<int64_t>> createInitializedMatrix(
std::size_t n) {
std::vector<std::vector<int64_t>> matrix(
n, std::vector<int64_t>(n, INF));
for (std::size_t i = 0; i < n; i++) {
matrix[i][i] = 0;
}
return matrix;
}
/** Function to test the Algorithm */
void tests() {
std::cout << "Initiating Predefined Tests..." << std::endl;
std::cout << "Initiating Test 1..." << std::endl;
std::vector<std::vector<int64_t>> adj1 = createInitializedMatrix(4);

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +73
if (dist[i][k] != INF && dist[k][j] != INF) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential integer overflow when adding edge weights. The expression 'dist[i][k] + dist[k][j]' can overflow before the comparison with 'dist[i][j]' is performed, leading to incorrect shortest path calculations. Consider checking if the addition would overflow before performing it, or restructure the comparison to avoid addition.

Suggested change
if (dist[i][k] != INF && dist[k][j] != INF) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
int64_t dik = dist[i][k];
int64_t dkj = dist[k][j];
if (dik != INF && dkj != INF) {
// Check for potential overflow/underflow before addition
bool will_overflow = false;
if (dkj > 0 && dik > std::numeric_limits<int64_t>::max() - dkj) {
will_overflow = true;
} else if (dkj < 0 && dik < std::numeric_limits<int64_t>::min() - dkj) {
will_overflow = true;
}
if (!will_overflow) {
int64_t through_k = dik + dkj;
if (through_k < dist[i][j]) {
dist[i][j] = through_k;
}
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant