CP
Patterns

Graph

# undirected graph
G = defaultdict(list)
for a, b in edges:
    G[a].append(b)
    G[b].append(a)

# directed graph
G = defaultdict(list)
for a, b in edges:
    G[a].append(b)

# weighted graph
G = defaultdict(dict)
for a, b, weight in edges:
    G[a][b] = weight
    G[b][a] = weight
visited = set()

def dfs(node: int) -> None:
    if node in visited:
        return

    visited.add(node)

    for nei in G[node]:
        dfs(nei)

# or iterative
stack = [start]
visited = set()

while stack:
    node = stack.pop()
    if node in visited:
        continue

    visited.add(node)

    for nei in G[node]:
        stack.append(nei)
q = deque([start])
visited = set([start])

while q:
    node = q.popleft()

    for nei in G[node]:
        if nei not in visited:
            visited.add(nei)
            q.append(nei)