Given an undirected, weighted graph with V vertices numbered from 0 to V-1 and E edges, represented by a 2d array edges[][], where edges[i] = [u, v, w] represents the edge between the nodes u and v having w edge weight.
Your task is to find the minimum weight cycle in this graph.
Examples:
Input: V = 5, edges[][] = [[0, 1, 2], [1, 2, 2], [1, 3, 1], [1, 4, 1], [0, 4, 3], [2, 3, 4]]
Output: 6 Explanation:
Minimum-weighted cycle is 0 → 1 → 4 → 0 with a total weight of 6(2 + 1 + 3)
Input: V = 5, edges[][] = [[0, 1, 3], [1, 2, 2], [0, 4, 1], [1, 4, 2], [1, 3, 1], [3, 4, 2], [2, 3, 3]]
Output: 5 Explanation:
Minimum-weighted cycle is 1 → 3 → 4 → 1 with a total weight of 5(1 + 2 + 2)
Constraints:
1 ≤ V ≤ 100
1 ≤ E = edges.size() ≤ 103
1 ≤ edges[i][j] ≤ 100
Approach 01:
-
C++
-
Python
#include <vector>
#include <queue>
#include <unordered_map>
#include <climits>
using namespace std;
class Solution {
public:
int dijkstra(int source, int destination, unordered_map<int, vector<pair<int, int>>>& adjacencyList, int vertexCount) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> minHeap;
vector<int> minDistance(vertexCount, INT_MAX);
minHeap.push({0, source});
while (!minHeap.empty()) {
int currentDistance = minHeap.top().first;
int currentNode = minHeap.top().second;
minHeap.pop();
for (auto& neighbor : adjacencyList[currentNode]) {
int neighborNode = neighbor.first;
int edgeWeight = neighbor.second;
// Skip the edge we're currently checking to form the cycle
if ((currentNode == source && neighborNode == destination) ||
(currentNode == destination && neighborNode == source)) {
continue;
}
if (currentDistance + edgeWeight < minDistance[neighborNode]) {
minDistance[neighborNode] = currentDistance + edgeWeight;
minHeap.push({minDistance[neighborNode], neighborNode});
}
}
}
return minDistance[destination];
}
int findMinCycle(int vertexCount, vector<vector<int>>& edges) {
unordered_map<int, vector<pair<int, int>>> adjacencyList;
for (const auto& edge : edges) {
int nodeU = edge[0];
int nodeV = edge[1];
int weight = edge[2];
adjacencyList[nodeU].emplace_back(nodeV, weight);
adjacencyList[nodeV].emplace_back(nodeU, weight);
}
int shortestCycleLength = INT_MAX;
for (const auto& edge : edges) {
int cyclePath = dijkstra(edge[0], edge[1], adjacencyList, vertexCount);
if (cyclePath != INT_MAX) {
shortestCycleLength = min(shortestCycleLength, cyclePath + edge[2]);
}
}
return shortestCycleLength;
}
};
import heapq
from typing import List
from collections import defaultdict
class Solution:
def dijkstra(self, source: int, destination: int, adjacencyList: dict, vertexCount: int) -> int:
minHeap = [(0, source)]
minDistance = [float('inf')] * vertexCount
while minHeap:
currentDistance, currentNode = heapq.heappop(minHeap)
for neighborNode, edgeWeight in adjacencyList[currentNode]:
# Skip the edge being checked
if (currentNode == source and neighborNode == destination) or \
(currentNode == destination and neighborNode == source):
continue
if currentDistance + edgeWeight < minDistance[neighborNode]:
minDistance[neighborNode] = currentDistance + edgeWeight
heapq.heappush(minHeap, (minDistance[neighborNode], neighborNode))
return minDistance[destination]
def findMinCycle(self, vertexCount: int, edges: List[List[int]]) -> int:
adjacencyList = defaultdict(list)
for nodeU, nodeV, weight in edges:
adjacencyList[nodeU].append((nodeV, weight))
adjacencyList[nodeV].append((nodeU, weight))
shortestCycleLength = float('inf')
for nodeU, nodeV, weight in edges:
cyclePath = self.dijkstra(nodeU, nodeV, adjacencyList, vertexCount)
if cyclePath != float('inf'):
shortestCycleLength = min(shortestCycleLength, cyclePath + weight)
return shortestCycleLength
Time Complexity:
- Building the Adjacency List:
Takes \( O(e) \), where \( e \) is the number of edges.
- Dijkstra’s Algorithm per Edge:
Dijkstra runs in \( O((v + e) \log v) \), and we run it once for each edge, so total becomes \( O(e (v + e) \log v) \).
- Total Time Complexity:
\( O(e (v + e) \log v) \)
Space Complexity:
- Adjacency List:
Stores all edges: \( O(e) \)
- Distance Vector and Priority Queue:
Each run of Dijkstra uses \( O(v) \) space.
- Total Space Complexity:
\( O(e + v) \)



