Practice GFG · Detect Cycle in an Undirected Graph · LeetCode 261 · Graph Valid Tree (related)
GraphsDFSUndirectedParent Track

Cycle Detection · Undirected Graph

In an undirected graph every edge is a two-way street, so you'll always "see" the node you came from. The trick: ignore your parent. Any other already-visited neighbor means a cycle.

The idea

DFS from any node, remembering who you came from (parent). When you reach a neighbor that's already visited and isn't your parent, you've found a second way into that node, that's a cycle.

Why track parent

  • Edge u–v is stored both ways
  • From v you'll always see u again
  • Skipping the parent avoids that false alarm
  • Repeat DFS per component for disconnected graphs

Trace the DFS

Unvisited Current Visited Cycle edge
slowfast
Step 0
Visited
0
At node
–
Parent
–
Cycle?
?

C++

bool dfs(int u, int parent, vector<vector<int>>& adj, vector<bool>& vis) {
    vis[u] = true;
    for (int v : adj[u]) {
        if (!vis[v]) {
            if (dfs(v, u, adj, vis)) return true;
        } else if (v != parent) {
            return true;      // visited & not parent → cycle
        }
    }
    return false;
}

bool hasCycle(int n, vector<vector<int>>& adj) {
    vector<bool> vis(n, false);
    for (int i = 0; i < n; i++)
        if (!vis[i] && dfs(i, -1, adj, vis))
            return true;   // check every component
    return false;
}
Time
O(V + E)

Standard DFS, each vertex and edge touched once.

Space
O(V)

Visited array plus recursion stack depth.

Signal
non-parent

A visited neighbor that isn't the parent = the second path into a node.

  • Directed vs undirected differ fundamentally: directed uses 3-color (gray = on path); undirected uses parent-skip.
  • Union-Find is the slick alternative: process edges, if both endpoints already share a root, that edge closes a cycle. That's exactly LC 684.
  • A connected undirected graph with V nodes is a tree iff it has exactly V-1 edges and no cycle.
  • Watch out for parallel edges / self-loops, they're cycles too and the simple parent check may need tweaks.
  • Always loop over all nodes, the graph may have multiple disconnected components.