Cycle Detection in Undirected Graph in DSA C - Time & Space Complexity
We want to know how the time needed to find a cycle in an undirected graph changes as the graph grows.
How does the number of nodes and edges affect the work done?
Analyze the time complexity of the following code snippet.
// Detect cycle using DFS in undirected graph
bool dfs(int node, int parent, vector<int> adj[], vector<bool> &visited) {
visited[node] = true;
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
if (dfs(neighbor, node, adj, visited))
return true;
} else if (neighbor != parent) {
return true;
}
}
return false;
}
bool isCycle(int V, vector<int> adj[]) {
vector<bool> visited(V, false);
for (int i = 0; i < V; i++) {
if (!visited[i]) {
if (dfs(i, -1, adj, visited))
return true;
}
}
return false;
}
This code checks if an undirected graph has a cycle by visiting nodes using depth-first search.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: DFS visits each node and explores all its neighbors.
- How many times: Each node and edge is visited once during the DFS traversal.
As the graph grows, the time to check all nodes and edges grows roughly in proportion to their count.
| Input Size (V = nodes, E = edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 40 visits (nodes + edges) |
| 100 nodes, 200 edges | About 500 visits |
| 1000 nodes, 3000 edges | About 4000 visits |
Pattern observation: The work grows roughly as the sum of nodes and edges, so doubling nodes and edges roughly doubles the work.
Time Complexity: O(V + E)
This means the time grows linearly with the number of nodes plus the number of edges in the graph.
[X] Wrong: "The DFS visits every edge multiple times, so the time is much higher than O(V + E)."
[OK] Correct: Each edge is checked only twice (once from each node), so the total work is still proportional to V + E, not more.
Understanding this time complexity helps you explain how graph traversal scales and why DFS is efficient for cycle detection in undirected graphs.
"What if we used BFS instead of DFS for cycle detection? How would the time complexity change?"
Practice
Solution
Step 1: Understand DFS traversal in undirected graph
DFS visits nodes and tracks the parent node to avoid false cycle detection.Step 2: Detect cycle condition
If a visited node is found that is not the parent, it means a back edge exists, indicating a cycle.Final Answer:
If we visit a node that is already visited and is not the parent, a cycle exists. -> Option CQuick Check:
Cycle detection in undirected graph = check visited node not parent [OK]
- Ignoring the parent node in cycle check
- Assuming disconnected graph always has cycles
- Confusing edge count with cycle presence
Solution
Step 1: Identify parameters needed for DFS cycle detection
We need current node, parent node, visited array, adjacency matrix, and number of nodes.Step 2: Match function signature with parameters
bool dfs(int node, int parent, int visited[], int graph[][100], int n) includes all required parameters with correct types and order.Final Answer:
bool dfs(int node, int parent, int visited[], int graph[][100], int n) -> Option AQuick Check:
DFS signature includes node, parent, visited, graph, size [OK]
- Omitting parent parameter
- Wrong return type for DFS
- Missing graph size parameter
int graph[4][4] = {
{0, 1, 0, 0},
{1, 0, 1, 1},
{0, 1, 0, 0},
{0, 1, 0, 0}
};
If we run cycle detection using DFS starting from node 0, what will be the output?Solution
Step 1: Analyze graph edges from adjacency matrix
Edges: 0-1, 1-2, 1-3. Node 1 connects to nodes 0, 2, 3.Step 2: Check for cycle using DFS
Starting at 0, DFS visits 1, then 2 and 3. Node 1 connects back to 0 (parent), no cycle there. No back edge to visited non-parent node is found, so no cycle.Final Answer:
No cycle detected -> Option BQuick Check:
Graph edges form a tree structure = No cycle [OK]
- Assuming any connected graph has cycle
- Ignoring parent node in cycle check
- Confusing adjacency matrix indexing
bool dfs(int node, int parent, int visited[], int graph[][100], int n) {
visited[node] = 1;
for (int i = 0; i < n; i++) {
if (graph[node][i] == 1) {
if (!visited[i]) {
if (dfs(i, node, visited, graph, n))
return true;
} else if (i != parent) {
return true;
}
}
}
return false;
}
Solution
Step 1: Check initialization of visited array
The code snippet does not show visited array initialization, which is required to mark nodes unvisited before DFS.Step 2: Verify other parameters and logic
Parent is passed correctly, adjacency matrix access is within bounds, and return type bool is appropriate for cycle detection.Final Answer:
The visited array is not initialized before calling dfs. -> Option AQuick Check:
Initialize visited[] before DFS to avoid incorrect results [OK]
- Forgetting to initialize visited array
- Passing wrong parent in recursion
- Misusing return type for DFS
0: 1, 2 1: 0, 3 2: 0, 3 3: 1, 2Using cycle detection with DFS, which nodes form the cycle and why?
Solution
Step 1: Analyze adjacency lists for cycles
Edges: 0-1, 0-2, 1-3, 2-3. These edges connect nodes forming a square shape.Step 2: Identify cycle involving all nodes
Starting at 0, path 0->1->3->2->0 forms a closed loop including all four nodes, indicating a cycle involving nodes 0,1,2,3.Final Answer:
Nodes 0, 1, 2, 3 form a cycle because they form a closed loop through all edges. -> Option DQuick Check:
Cycle includes all nodes forming closed loop [OK]
- Identifying partial cycles ignoring full loop
- Confusing connected nodes with cycle nodes
- Missing edges that complete the cycle
Ready to prove it?
Pass the test and this pattern moves unknown
