πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

Graph Theory

Discrete MathematicsGraphs🟒 Free Lesson

Advertisement

Graph Theory


Definitions


Formulas


Python Implementations

Graph Representations

import numpy as np
from collections import defaultdict

# Adjacency Matrix
class AdjMatrixGraph:
    def __init__(self, n):
        self.n = n
        self.matrix = np.zeros((n, n), dtype=int)

    def add_edge(self, u, v, weight=1):
        self.matrix[u][v] = weight
        self.matrix[v][u] = weight  # undirected

    def has_edge(self, u, v):
        return self.matrix[u][v] != 0

    def degree(self, v):
        return int(self.matrix[v].sum())

# Adjacency List
class AdjListGraph:
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self, u, v, weight=1):
        self.graph[u].append((v, weight))
        self.graph[v].append((u, weight))

    def neighbors(self, v):
        return self.graph[v]

    def degree(self, v):
        return len(self.graph[v])

# Example usage
g = AdjListGraph()
edges = [(0,1), (0,2), (1,2), (2,3), (3,4)]
for u, v in edges:
    g.add_edge(u, v)

print(f"Degree of node 2: {g.degree(2)}")
print(f"Neighbors of 2: {g.neighbors(2)}")

BFS and DFS Traversal

from collections import defaultdict, deque

class Graph:
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self, u, v):
        self.graph[u].append(v)
        self.graph[v].append(u)

    def bfs(self, start):
        visited = set()
        queue = deque([start])
        visited.add(start)
        order = []
        while queue:
            node = queue.popleft()
            order.append(node)
            for neighbor in self.graph[node]:
                if neighbor not in visited:
                    visited.add(neighbor)
                    queue.append(neighbor)
        return order

    def dfs(self, start, visited=None):
        if visited is None:
            visited = set()
        visited.add(start)
        order = [start]
        for neighbor in self.graph[start]:
            if neighbor not in visited:
                order.extend(self.dfs(neighbor, visited))
        return order

    def is_connected(self, n_vertices):
        visited = self.bfs(0)
        return len(visited) == n_vertices

g = Graph()
for u, v in [(0,1), (0,2), (1,3), (2,3), (3,4)]:
    g.add_edge(u, v)

print("BFS:", g.bfs(0))
print("DFS:", g.dfs(0))
print("Connected:", g.is_connected(5))

Euler Path Detection

def has_euler_path(graph, n_vertices):
    odd_degree = [v for v in range(n_vertices) if graph.degree(v) % 2 != 0]
    return len(odd_degree) == 0 or len(odd_degree) == 2

def euler_circuit_exists(graph, n_vertices):
    return all(graph.degree(v) % 2 == 0 for v in range(n_vertices))

Graph Coloring

def greedy_coloring(graph, n_vertices):
    result = [-1] * n_vertices
    result[0] = 0
    for u in range(1, n_vertices):
        available = set(range(n_vertices))
        for neighbor in graph[u]:
            if result[neighbor] != -1:
                available.discard(result[neighbor])
        result[u] = min(available)
    return result

def chromatic_number_upper_bound(n_vertices):
    return n_vertices  # Worst case: complete graph

Planarity


Applications in AI/ML


Common Mistakes

MistakeCorrection
Assuming all graphs are simpleA graph may have loops (edge from vertex to itself) and multiple edges between the same pair
Confusing directed and undirected degreesIn directed graphs, track in-degree and out-degree separately
Ignoring isolated verticesVertices with degree 0 still count toward
Misapplying Euler's formulaEuler's formula only applies to connected planar graphs
Assuming planarity for dense graphs has only 5 vertices but is non-planar
Forgetting the Handshaking Lemma implies even sumThe sum of all degrees is always even, so the number of odd-degree vertices is always even
Using BFS when DFS is neededBFS finds shortest paths; DFS is better for cycle detection and topological sorting
Confusing isomorphism with same degree sequenceSame degree sequence does not guarantee isomorphism

Interview Questions

  1. How would you detect a cycle in an undirected graph? Use DFS and check for back edges, or use Union-Find to detect if adding an edge connects two already-connected vertices.

  2. What is the difference between BFS and DFS? BFS explores level by level using a queue, finding shortest paths in unweighted graphs. DFS explores as deep as possible using a stack/recursion, useful for topological sort and cycle detection.

  3. How do you check if a graph is bipartite? Use BFS or DFS with 2-coloring. If we can color the graph with 2 colors such that no adjacent vertices share a color, it is bipartite.

  4. What is the time complexity of graph traversal? BFS and DFS both run in time using adjacency lists.

  5. How do you find connected components? Run BFS/DFS from each unvisited vertex. Each traversal marks one connected component.

  6. What is a topological sort and when is it used? A topological sort orders vertices in a DAG such that all edges go from earlier to later. Used in task scheduling and dependency resolution.

  7. How do you find the shortest path in a weighted graph? Use Dijkstra's algorithm for non-negative weights, Bellman-Ford for graphs with negative weights, or Floyd-Warshall for all-pairs shortest paths.

  8. What is graph coloring used for? Map coloring, register allocation in compilers, scheduling exams without conflicts, and frequency assignment in wireless networks.


Practice Problems


Quick Reference

ConceptFormula/Description
Edges in
Handshaking Lemma
Euler's Formula (connected planar)
Planar edge bound for
Bipartite edges
BFS time complexity
DFS time complexity
Chromatic numberMinimum colors for proper coloring
Euler pathExists iff 0 or 2 odd-degree vertices
Hamilton cycleNP-complete to determine existence

Cross-References

  • Trees -> 075-discrete-trees.mdx: Trees are connected acyclic graphs; a special case of graph theory
  • Recurrence Relations -> 076-discrete-recurrence.mdx: Graph traversal algorithms have recursive definitions
  • Number Theory -> 077-discrete-number-theory.mdx: Modular arithmetic used in graph hashing
  • Boolean Algebra -> 078-discrete-boolean.mdx: Boolean functions on graph properties
  • Automata Theory -> 079-discrete-automata.mdx: State diagrams are directed graphs
  • Applications -> 080-discrete-applications.mdx: Network flow, cryptography, and scheduling use graphs

Need Expert Mathematics Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement