Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find shortest cycle length holding target in python
Finding the shortest cycle containing a specific target node in a directed graph is a common graph problem. We can solve this using Breadth-First Search (BFS) to explore paths from the target node until we find a cycle back to it.
Problem Understanding
Given an adjacency list representation of a directed graph and a target node, we need to find the shortest cycle that contains the target node. If no such cycle exists, return -1.
Algorithm Approach
We use BFS starting from the target node to explore all possible paths. When we encounter the target node again during traversal, we've found a cycle ?
class Solution:
def solve(self, graph, target):
visited = set()
queue = [target]
length = 0
while queue:
length += 1
next_queue = []
for current_node in queue:
for neighbor in graph[current_node]:
if neighbor == target:
return length
if neighbor in visited:
continue
visited.add(neighbor)
next_queue.append(neighbor)
queue = next_queue
return -1
# Test the solution
solution = Solution()
graph = [[1, 4], [2], [3], [0, 1], []]
target = 3
result = solution.solve(graph, target)
print(f"Shortest cycle length containing node {target}: {result}")
The output of the above code is ?
Shortest cycle length containing node 3: 3
How It Works
The algorithm works in layers using BFS:
- Initialize: Start with target node in queue, empty visited set
- Level-by-level exploration: For each level, explore all neighbors
- Cycle detection: If we reach the target again, return current length
- Avoid revisiting: Mark nodes as visited to prevent infinite loops
Example Walkthrough
# Let's trace through the algorithm step by step
def solve_with_trace(graph, target):
visited = set()
queue = [target]
length = 0
print(f"Starting BFS from target node: {target}")
while queue:
length += 1
print(f"\nLevel {length}: Exploring nodes {queue}")
next_queue = []
for current_node in queue:
print(f" From node {current_node}, neighbors: {graph[current_node]}")
for neighbor in graph[current_node]:
if neighbor == target:
print(f" Found cycle back to {target}! Length: {length}")
return length
if neighbor in visited:
print(f" Node {neighbor} already visited, skipping")
continue
visited.add(neighbor)
next_queue.append(neighbor)
print(f" Added node {neighbor} to next level")
queue = next_queue
print(f" Visited so far: {visited}")
return -1
# Test with detailed trace
graph = [[1, 4], [2], [3], [0, 1], []]
target = 3
result = solve_with_trace(graph, target)
print(f"\nFinal result: {result}")
The output of the above code is ?
Starting BFS from target node: 3
Level 1: Exploring nodes [3]
From node 3, neighbors: [0, 1]
Added node 0 to next level
Added node 1 to next level
Visited so far: {0, 1}
Level 2: Exploring nodes [0, 1]
From node 0, neighbors: [1, 4]
Node 1 already visited, skipping
Added node 4 to next level
From node 1, neighbors: [2]
Added node 2 to next level
Visited so far: {0, 1, 4, 2}
Level 3: Exploring nodes [4, 2]
From node 4, neighbors: []
From node 2, neighbors: [3]
Found cycle back to 3! Length: 3
Final result: 3
Time and Space Complexity
| Metric | Complexity | Explanation |
|---|---|---|
| Time | O(V + E) | Visit each vertex and edge once |
| Space | O(V) | Visited set and queue storage |
Conclusion
This BFS approach efficiently finds the shortest cycle containing a target node by exploring paths level by level. The algorithm guarantees the shortest cycle due to BFS's nature of exploring nodes in order of distance from the starting point.
