Connected Components Operations
Node
Edge-
Run
Check↔
100%
Ctrl + scroll to zoom
Identify distinct connected groups in a graph - watch components get colored one by one.
Time O(V + E) · Space O(V)
from typing import Dict, Set, List, Any
def find_components(graph: Dict[Any, Set[Any]]) -> List[Set[Any]]:
"""
Find all connected components using DFS.
Args:
graph: Adjacency list for undirected graph {node: {neighbors}}
Returns:
List of sets, where each set contains vertices in one component
"""
visited = set()
components = []
def _dfs(node: Any, component: Set[Any]) -> None:
visited.add(node)
component.add(node)
for neighbor in graph.get(node, set()):
if neighbor not in visited:
_dfs(neighbor, component)
for node in graph:
if node not in visited:
component: Set[Any] = set()
_dfs(node, component)
components.append(component)
return components
def count_components(graph: Dict[Any, Set[Any]]) -> int:
"""
Count the number of connected components.
Args:
graph: Adjacency list for undirected graph
Returns:
Number of connected components
"""
return len(find_components(graph))
def are_connected(graph: Dict[Any, Set[Any]], u: Any, v: Any) -> bool:
"""
Check if two vertices are in the same connected component.
Args:
graph: Adjacency list for undirected graph
u: First vertex
v: Second vertex
Returns:
True if u and v are connected, False otherwise
"""
if u not in graph or v not in graph:
return False
visited = set()
def _dfs(node: Any) -> bool:
if node == v:
return True
visited.add(node)
for neighbor in graph.get(node, set()):
if neighbor not in visited:
if _dfs(neighbor):
return True
return False
return _dfs(u)
def get_component(graph: Dict[Any, Set[Any]], vertex: Any) -> Set[Any]:
"""
Get the connected component containing a specific vertex.
Args:
graph: Adjacency list for undirected graph
vertex: The vertex to find the component for
Returns:
Set of all vertices in the same component as vertex
"""
if vertex not in graph:
return set()
component: Set[Any] = set()
visited = set()
def _dfs(node: Any) -> None:
visited.add(node)
component.add(node)
for neighbor in graph.get(node, set()):
if neighbor not in visited:
_dfs(neighbor)
_dfs(vertex)
return component
# Example usage and demonstration
if __name__ == "__main__":
# Example graph with 3 connected components
#
# Component 1: Component 2: Component 3:
# A --- B D --- E G
# | | |
# C --- F H
#
example_graph = {
"A": {"B", "C"},
"B": {"A", "F"},
"C": {"A", "F"},
"F": {"B", "C"},
"D": {"E", "H"},
"E": {"D"},
"H": {"D"},
"G": set(), # Isolated vertex
}
print("Connected Components (DFS):", find_components(example_graph))
print("Number of Components:", count_components(example_graph))
print("A and F connected?", are_connected(example_graph, "A", "F"))
print("A and D connected?", are_connected(example_graph, "A", "D"))
print("Component containing A:", get_component(example_graph, "A"))
Connected components are maximal sets of vertices in an undirected graph where every pair is connected by a path. Finding them reveals the graph's structure and isolated subgraphs. Two common approaches are DFS-based traversal and the Union-Find data structure.
DFS approach: iterate through all vertices; for each unvisited vertex, run DFS/BFS to mark all reachable vertices as one component. Union-Find approach: for each edge, union the two endpoints; vertices in the same set belong to the same component.