Graph Theory
Connectivity
Bipartite Graphs
Cycle Detection
Tree Structures

graph algorithm finding if graph is connected, bipartite, has cycle and is a tree

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

For undirected graphs, common checks include connectivity, bipartiteness, cycle detection, and whether the graph is a tree. These properties are closely related and can often be derived with one traversal strategy.

This article shows a BFS/DFS-based approach that computes all four properties efficiently.

Core Sections

1) Connectivity check

A graph is connected if all vertices are reachable from one start node.

python
1from collections import deque
2
3def bfs_component(adj, start):
4    q = deque([start])
5    seen = {start}
6    while q:
7        u = q.popleft()
8        for v in adj[u]:
9            if v not in seen:
10                seen.add(v)
11                q.append(v)
12    return seen

2) Bipartite check by 2-coloring

python
1def is_bipartite(adj, n):
2    color = {}
3    for s in range(n):
4        if s in color:
5            continue
6        color[s] = 0
7        q = deque([s])
8        while q:
9            u = q.popleft()
10            for v in adj[u]:
11                if v not in color:
12                    color[v] = 1 - color[u]
13                    q.append(v)
14                elif color[v] == color[u]:
15                    return False
16    return True

3) Cycle detection in undirected graph

python
1def has_cycle(adj, n):
2    seen = set()
3    for s in range(n):
4        if s in seen:
5            continue
6        q = deque([(s, -1)])
7        seen.add(s)
8        while q:
9            u, p = q.popleft()
10            for v in adj[u]:
11                if v not in seen:
12                    seen.add(v)
13                    q.append((v, u))
14                elif v != p:
15                    return True
16    return False

4) Tree condition

For undirected graph with n nodes, it is a tree iff connected and edges count is n-1.

5) Combined classifier

Build one helper that returns all properties for diagnostics.

6) Production checklist for graph property analysis

Turning a working snippet into production-ready behavior requires explicit validation beyond unit examples. Start by defining measurable acceptance criteria for correctness, reliability, and performance. Correctness should include at least one golden input-output case and one edge case. Reliability should include how failures are surfaced and whether retries are safe. Performance should be measured with representative input size, not tiny toy examples that hide scaling issues. Once these criteria are written down, keep them close to the code so maintainers know what guarantees must hold during refactors.

Operational readiness also depends on environment clarity. Document runtime version constraints, required configuration keys, and any external dependencies such as services, files, or credentials. Most regressions in this class of problem are not algorithmic; they come from environment drift, dependency upgrades, or subtle API behavior changes. Add one smoke test that runs in CI and one failure-mode check that verifies observability. The failure-mode check should confirm that logs and error messages are actionable, not generic. If a team member cannot quickly identify the failing component from logs, incident response will be slower than necessary.

A pragmatic rollout sequence is:

  1. Run static checks and tests in CI.
  2. Execute a smoke test with realistic data shape.
  3. Trigger one expected failure mode and verify logging.
  4. Deploy behind a feature flag or staged rollout when possible.
  5. Monitor defined metrics during a stabilization window.
bash
1# Example release hygiene
2make lint
3make test
4./scripts/smoke_check.sh

Finally, define ownership and rollback up front. Specify who responds when checks fail, what threshold triggers rollback, and which fallback mode keeps user-facing behavior acceptable. Even small utilities should have explicit limits and non-goals recorded in documentation. That prevents accidental overextension and helps future contributors decide whether to iterate on the existing approach or replace it. Revisit this checklist after framework upgrades, because behavior assumptions that were once valid can change with new runtime defaults or deprecations.

Common Pitfalls

  • Forgetting disconnected components when checking bipartite/cycle.
  • Miscounting edges in undirected adjacency lists (double counting).
  • Applying tree condition without connectivity validation.
  • Using recursion DFS on very deep graphs and hitting recursion limits.
  • Mixing directed-graph logic with undirected checks.

Summary

Connectivity, bipartite status, cycle presence, and tree property can be computed with linear-time traversals. Combining these checks in one utility simplifies graph diagnostics and avoids inconsistent algorithm assumptions.


Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms