Module 5 Graphs
28/11/2025 School of Computer Engineering, MIT, Manipal 1
The Origin of Graph Theory – The
Koenigsberg Bridge Problem
• The first recorded use of graphs dates back to 1736 by Leonhard Euler.
• The problem was based on the city of Koenigsberg, divided by the
Pregel River.
• There were four land areas (A, B, C, D) connected by seven bridges (a–
g).
• Problem Statement:
• Starting from any land area, is it possible to cross each bridge exactly
once and return to the starting point?
28/11/2025 School of Computer Engineering, MIT, Manipal 2
The bridges
of
Koenigsber
28/11/2025 School of Computer Engineering, MIT, Manipal 3
Euler’s Solution and Significance
• Euler represented the problem using a graph (multigraph):
• Vertices → Land areas (A, B, C, D)
• Edges → Bridges (a–g)
• He proved that no such walk exists where every bridge is crossed once and
returns to the start.
• Reason: More than two vertices have an odd degree (odd number of bridges).
• Significance:
• This discovery marked the birth of graph theory.
• Euler’s reasoning applies to all graphs, not just this problem.
28/11/2025 School of Computer Engineering, MIT, Manipal 4
Graph Basics
• A graph, G=(V, E), consists of two sets:
• a finite set of vertices(V), and
• a finite, possibly empty set of edges(E)
• V(G) and E(G) represent the sets of vertices and edges of G, respectively
• Undirected graph
• The pairs of vertices representing any edges is unordered
• e.g., (v0, v1) and (v1, v0) represent the same edge
• Directed graph
• Each edge as a directed pair of vertices
• e.g. <v0, v1> represents an edge, v0 is the tail and v1 is the head
28/11/2025 School of Computer Engineering, MIT, Manipal 5
Examples for Graph
0 0 0
1 2 1 2
1
3
3 4 5 6
G1 2
G2
complete graph incomplete graph G3
V(G1)={0,1,2,3} E(G1)={(0,1),(0,2),(0,3),(1,2),
(1,3),(2,3)}
V(G2)={0,1,2,3,4,5,6} E(G2)={(0,1),(0,2),(1,3),(1,4),
(2,5),(2,6)}
V(G3)={0,1,2} E(G3)={<0,1>,<1,0>,<1,2>}
CHAPTER 6 6
Complete Graph
• Definition: A complete graph is a graph that has the maximum
number of edges.
• Undirected Graph: For an undirected graph with n vertices, the
maximum number of edges is: n(n-1)/2
• Directed Graph: For a directed graph with n vertices, the
maximum number of edges is: n(n-1)
• Example: Graph G1 (from the previous slide) is a complete
graph.
28/11/2025 CHAPTER 6 7
Adjacent and Incident
If (v0, v1) is an edge in an undirected
graph,
v0 and v1 are adjacent
The edge (v0, v1) is incident on vertices v0 and
v1
If <v0, v1> is an edge in a directed graph
v0 is adjacent to v1, and v1 is adjacent from v0
The edge <v0, v1> is incident on v0 and v1
CHAPTER 6 8
Example of a graph with feedback loops and a
multigraph
0
0 2 1 3
1 2 multigraph:
self edge multiple
(a) (b)
occurrences
of the same edge
CHAPTER 6 9
Subgraph and Path
• A subgraph of G is a graph G’ such that V(G’) is a
subset of V(G) and E(G’) is a subset of E(G)
• A path from vertex vp to vertex vq in a graph G, is a
sequence of vertices, vp, vi1, vi2, ..., vin, vq,
such that (vp, vi1), (vi1, vi2), ..., (vin, vq) are edges in an
undirected graph.
• The length of a path is the number of edges on it
28/11/2025 School of Computer Engineering, MIT, Manipal 10
Subgraphs of G1 and G3
0 0 0 1 2 0
1 2 1 2 3 1 2
3
3
G1 (i) (ii) (iii)
(iv)
(a) Some of the subgraph of G1
0 0 0 0
0
1 1 1
1
2 2
2 (i) (ii) (iii) (iv)
(b) Some of the subgraph of G3
G3 CHAPTER 6 11
Simple Path and Style
• A simple path is a path in which all vertices, except possibly
the first and the last, are distinct
• A cycle is a simple path in which the first and the last vertices
are the same
• In an undirected graph G, two vertices, v0 and v1, are
connected if there is a path in G from v0 to v1
• An undirected graph is connected if, for every pair of distinct
vertices vi, vj, there is a path from vi to vj
28/11/2025 CHAPTER 6 12
Connected
0 0
1 2 1 2
3
3 4 5 6
G1
G2
tree (acyclic graph)
CHAPTER 6 13
Degree
The degree of a vertex is the number of edges incident to
that vertex
For directed graph,
the in-degree of a vertex v is the number of edges
that have v as the head
the out-degree of a vertex v is the number of edges
that have v as the tail
if di is the degree of a vertex i in a graph G with n
vertices and e edges, the number of edges is
n 1
e ( d
0
i
)/ 2
14
undirected graph
3 0
0 2
1 2
degree 3 1 2 3 3 3
3 4 5 6
3
3 1 1 1 1
G1
G2
0 in:1, out: 1
directed graph
in-degree
out-degree 1 in: 1, out: 2
2 in: 1, out: 0
G3
0
• Adjacency matrices
1 2
• Adjacency lists 3
G1
0
0 4
2 1 5 6 1
3 7 2
G4
G3
CHAPTER 6 17
Graph representation – undirected
Graph Adjacency list Adjacency matrix
28/11/2025 ref. Introduction to Algorithms by Thomas Cormen 18
Graph representation – directed
Graph Adjacency list Adjacency matrix
28/11/2025 ref. Introduction to Algorithms by Thomas Cormen 19
Adjacency Matrix
Let G=(V,E) be a graph with n vertices.
The adjacency matrix of G is a two-dimensional
n by n array, say adj_mat
If the edge (vi, vj) is in E(G), adj_mat[i][j]=1
If there is no such edge in E(G), adj_mat[i][j]=0
The adjacency matrix for an undirected graph is
symmetric; the adjacency matrix for a digraph
need not be symmetric
CHAPTER 6 20
Examples for Adjacency Matrix
0 0 4
0
2 1 5
1 2
3 6
3 1
0 1 1 1 0 1 0
1 0 1 1 7
1 0 1
2 0 1 1 0 0 0 0 0
1 1 0 1 0 0 0 1
0 0 1 0 0 0 0
1 1 1 0
1 0 0 1 0 0 0 0
G2
G1 0 1 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 1 0 1 0
symmetric 0 0 0 0 0 1 0 1
undirected: n2/2 0 0 0 0 0 0 1 0
directed: n2 CHAPTER 6
G4 21
Adjacency lists
0
0 3 1 2
1
1 2 2 3 0 1
2 0
3 1 3 0
2
G1 0 1 2
G3
CHAPTER 6 22
Graph representation using adjacency
lists
• // Node structure for adjacency list • // Number of vertices currently in use
• typedef struct node { • int n = 0;
• int vertex; • // Function to create a new node
• struct node* next; • Node* createNode(int vertex) {
• } Node; • Node* newNode =
• // Array of adjacency lists (graph) (Node*)malloc(sizeof(Node));
• Node* graph[MAX_VERTICES]; • newNode->vertex = vertex;
• newNode->next = NULL;
• return newNode;
• }
28/11/2025 School of Computer Engineering, MIT, Manipal 23
Graph representation using adjacency
lists
• // Function to add an edge to the graph • // Function to display the adjacency list
(undirected)
• void displayGraph() {
• void addEdge(int src, int dest) {
• for (int i = 0; i < n; i++) {
• Node* newNode = createNode(dest);
• Node* temp = graph[i];
• newNode->next = graph[src];
• printf("Vertex %d: ", i);
• graph[src] = newNode;
• while (temp) {
• // For undirected graph, add an edge from dest to src
• printf("%d -> ", temp->vertex);
also
• • temp = temp->next; }
newNode = createNode(src);
• • printf("NULL\n"); }
newNode->next = graph[dest];
• • }
graph[dest]
28/11/2025
= newNode; }School of Computer Engineering, MIT, Manipal 24
Graph representation using adjacency
lists
• int main() { • printf("Enter each edge (source
destination):\n");
• printf("Enter the number of vertices: ");
• for (int i = 0; i < edges; i++) {
• scanf("%d", &n);
• int src, dest;
• // Initialize graph
• scanf("%d %d", &src, &dest);
• for (int i = 0; i < n; i++) {
• addEdge(src, dest); }
• graph[i] = NULL; }
• printf("\nAdjacency List
• int edges;
Representation:\n");
• printf("Enter the number of edges: ");
• displayGraph();
• scanf("%d", &edges);
• return 0;}
28/11/2025 School of Computer Engineering, MIT, Manipal 25
Graph representation using adjacency Matrix
void createGraph(int adj[MAX][MAX], int vertices, int edges, int directed)
{
int i, u, v;
// Initialize all entries to 0
for (i = 0; i < vertices; i++) {
for (int j = 0; j < vertices; j++) {
adj[i][j] = 0;
}
}
printf("Enter edges (u v) one by one:\n");
for (i = 0; i < edges; i++) {
scanf("%d%d", &u, &v);
adj[u][v] = 1;
if (!directed)
adj[v][u] = 1; // For undirected graph
}
} 26
Some Graph Operations
Traversal
Given G=(V,E) and vertex v, find all
wV,
such that w connects v.
Depth First Search (DFS)
preorder tree traversal
Breadth First Search (BFS)
level order tree traversal
CHAPTER 6 27
Depth First Search (DFS) – Concept
Overview
• DFS begins by visiting a starting vertex (v).
• Visiting means performing an operation (e.g., printing the vertex).
• From vertex v, we move to an unvisited adjacent vertex (w).
• The current position in v’s adjacency list is stored on a stack.
• The search continues deeper until a vertex (M) has no unvisited
adjacent vertices.
• At this point, we backtrack by removing a vertex from the stack
and continue.
28/11/2025 School of Computer Engineering, MIT, Manipal 28
Depth-first search
A • DFS explores a path all the way to a
leaf before backtracking and
B C exploring another path
• For example, after searching A, then
D E F G B, then D, the search backtracks and
tries another path from B
H I J K • Node are explored in the order A B D E
HLMNIOPCFGJKQ
L M N O P Q
DFS Algorithm (Iterative)
Algorithm IterativeDFS(G, source):
graph
1. Mark all vertices as not visited
2. Push source into stack
3. Mark source as visited
Adjacency matrix
4. While stack is not empty:
a. Pop top element from stack into u and Print it.
c. For each adjacent vertex v of u:
if v is not visited:
Push v into stack
Mark v as visited Adjacency list
30
void dfs(int a[10][10],int n,int source) DFS Algorithm (Iterative) Implementation
{ int visited[10],u,v,i;
for(i=1;i<=n;i++)
visited[i]=0;
int S[10],top=-1;
S[++top]=source;
visited[source]=1;
while(top>=0)
{ u=S[top--];
for(v=1;v<=n;v++)
{ if(a[u][v]==1 && visited[v]==0)
{
visited[v]=1; S[++top]=v;
}
}
print(u);
}} 31
DFS Algorithm (Recursive)
Algorithm DFS(G, v):
Input: Graph G = (V, E) and starting vertex v
Output: Nodes visited in depth-first order
1. Mark v as visited
2. Print v (or process it)
3. For each vertex u adjacent to v:
if u is not visited:
DFS(G, u)
32
DFS Recursive Implementation
• #define MAX_VERTICES 50 • // Visited array to mark visited vertices
• #define FALSE 0 • short int visited[MAX_VERTICES];
• #define TRUE 1 • int n; // Number of vertices
• // Node structure for adjacency list • // Function to create a new node
• typedef struct node { • Node* createNode(int vertex) {
• int vertex; • Node* newNode =
• struct node* next; (Node*)malloc(sizeof(Node));
• } Node; • newNode->vertex = vertex;
• // Graph representation (array of adjacency • newNode->next = NULL;
lists)
• return newNode; }
• Node* graph[MAX_VERTICES];
28/11/2025 School of Computer Engineering, MIT, Manipal 33
DFS Implementation
• // Function to add an edge to the graph (undirected) • // Depth First Search function
• void addEdge(int src, int dest) { • void dfs(int v) {
• Node* newNode = createNode(dest); • Node* w;
• newNode->next = graph[src]; • visited[v] = TRUE;
• graph[src] = newNode; • printf("%5d", v);
• // For undirected graph, also add the reverse edge • for (w = graph[v]; w != NULL; w = w-
• newNode = createNode(src); >next) {
• newNode->next = graph[dest]; • if (!visited[w->vertex])
• graph[dest] = newNode;} • dfs(w->vertex);
• } }
28/11/2025 School of Computer Engineering, MIT, Manipal 34
DFS Implementation
• // Initialize graph and visited array
• // Function to initialize visited array
• for (int i = 0; i < n; i++) {
• void initializeVisited() {
• graph[i] = NULL;
• for (int i = 0; i < n; i++)
• visited[i] = FALSE; }
• visited[i] = FALSE;}
• printf("Enter number of edges: ");
• int main() {
• scanf("%d", &edges);
• int edges, src, dest, startVertex;
• printf("Enter each edge (source destination):\n");
• printf("Enter number of vertices:
"); • for (int i = 0; i < edges; i++) {
• scanf("%d", &n); • scanf("%d %d", &src, &dest);
• addEdge(src, dest); }
28/11/2025 School of Computer Engineering, MIT, Manipal 35
DFS Implementation
• printf("Enter starting vertex for
DFS: ");
• scanf("%d", &startVertex);
• printf("\nDepth First Search
Traversal:\n");
• dfs(startVertex);
• printf("\n");
• return 0;
• }
28/11/2025 School of Computer Engineering, MIT, Manipal 36
Breadth First Search (BFS) – Concept
Overview
• BFS starts from a given vertex v and marks it as visited.
• It visits all vertices adjacent to v (neighbors of v).
• After visiting all neighbors, BFS proceeds to the next vertex in
the queue.
• This process continues level by level, visiting all vertices
reachable from the start vertex.
• BFS ensures that the shortest path (in terms of edges) from
the start vertex is found first.
28/11/2025 School of Computer Engineering, MIT, Manipal 37
Breadth-first search
A
• A breadth-first search (BFS) explores
nodes nearest the root before
B C exploring nodes further away
• For example, after searching A, then B,
D E F G
then C, the search proceeds with D, E,
F, G
H I J K
• Node are explored in the order A B C D
EFGHIJKLMNOPQ
L M N O P Q
BFS Implementation
• #define MAX_VERTICES 50 • short int visited[MAX_VERTICES];
• #define FALSE 0 • int n; // Number of vertices
• #define TRUE 1 • // Queue node structure
• // Node structure for adjacency list
• typedef struct queue {
• typedef struct node {
• int vertex;
• int vertex; • struct queue* link;
• struct node* next; • } QueueNode;
• } Node;
• typedef struct queue* queue_pointer;
• // Global graph and visited array
• Node* graph[MAX_VERTICES];
28/11/2025 School of Computer Engineering, MIT, Manipal 39
BFS Implementation
• void addq(queue_pointer* front, queue_pointer* • queue_pointer temp
rear, int vertex); =(queue_pointer)malloc(sizeof(QueueNode
));
• int deleteq(queue_pointer* front);
• temp->vertex = vertex;
• void bfs(int v);
• temp->link = NULL;
• Node* createNode(int vertex);
• if (*rear) {
• void addEdge(int src, int dest);
• (*rear)->link = temp;
-------------------- QUEUE FUNCTIONS --------------------
• } else {
• // Enqueue operation
• *front = temp; }
• void addq(queue_pointer* front, queue_pointer*
rear, int vertex) { • *rear = temp; }
28/11/2025 School of Computer Engineering, MIT, Manipal 40
BFS Implementation
• // Dequeue operation • Node* createNode(int vertex) {
• Node* newNode = (Node*)malloc(sizeof(Node));
• int deleteq(queue_pointer*
front) { • newNode->vertex = vertex;
• newNode->link = NULL;
• queue_pointer temp = *front;
• return newNode;}
• int item;
• void addEdge(int src, int dest) {
• if (!temp) • Node* newNode = createNode(dest);
• return -1; // queue empty • newNode->link = graph[src];
• item = temp->vertex; • graph[src] = newNode;
• newNode = createNode(src);
• *front = temp->link;
• newNode->link = graph[dest];
• free(temp);
• graph[dest] = newNode;}
• 28/11/2025 School of Computer Engineering, MIT, Manipal 41
return item; }
BFS Implementation
• void bfs(int v) { • if (!visited[w->vertex]) {
• Node* w; • printf("%5d", w->vertex);
• queue_pointer front = NULL, rear = • visited[w->vertex] = TRUE;
NULL;
• addq(&front, &rear, w-
• printf("%5d", v); >vertex);
• visited[v] = TRUE; • }
• addq(&front, &rear, v); • }
• while (front) { • }
• v = deleteq(&front); • int main()
• for (w = graph[v]; w; w = w->link) { • ….......
• 28/11/2025 School of Computer Engineering, MIT, Manipal 42
Graph Connectivity Using DFS/BFS
• Goal: Determine whether an undirected graph
is connected — i.e., every vertex is reachable
from any other vertex.
• Method:
• Perform a DFS(0) or BFS(0) starting from
vertex 0.
• After the traversal, check if all vertices have
been visited.
• Example:
• Applying dfs(0) on graph G4 visits only
vertices 0–3, but not 4–7.
• ⇒ Hence, graph G4 is not connected.
28/11/2025 School of Computer Engineering, MIT, Manipal 43
Connected Components
• A connected component is a maximal set of vertices where
each vertex is reachable from any other within the same set.
• Procedure:
• Initialize all vertices as unvisited.
• For each vertex v:
• If v is unvisited → call DFS(v) or BFS(v).
• All vertices visited in that call form one connected component.
• Repeat until all vertices are visited.
28/11/2025 School of Computer Engineering, MIT, Manipal 44
Function Example (connected):
• for (v = 0; v < n; v++)
• if (!visited[v]) {
• printf("Component: ");
• dfs(v);
• printf("\n");
• }
28/11/2025 School of Computer Engineering, MIT, Manipal 45
Spanning Tree (ST)
• A spanning tree is a minimal subgraph G’, such that
V(G’)=V(G) and G’ is connected. Spanning Tree is
always acyclic. 3 1 2
0
2 3 0
1 2
1 3 0
0 0 3
0 1 2
1 2 1 2 G1
3 3
ST1(G ST2(G CHAPTER 6 46
) )
Spanning Trees in Connected Graphs
• When a graph G is connected, a Depth First Search (DFS) or Breadth First Search
(BFS) starting at any vertex will visit all vertices in G.
• The traversal implicitly divides the edges into two sets:
• T (Tree edges): edges used/traversed during the search.
• N (Nontree edges): remaining edges not used in traversal.
• The edges in T form a tree that includes all vertices of G.
• Such a tree is called a Spanning Tree —
• A subgraph that includes all vertices of G and a subset of edges that form a tree (no
cycles).
• Each connected graph can have multiple spanning trees.
28/11/2025 School of Computer Engineering, MIT, Manipal 47
Tree and Nontree Edges –
Implementation View
During DFS/BFS traversal:
• When a new vertex w is visited from vertex v, the edge (v, w) is
added to the Tree Edge Set (T).
• These edges collectively form a Spanning Tree.
Pseudocode Integration:
• if (!visited[w->vertex]) {
• addEdgeToTree(v, w->vertex); // store (v, w) as tree edge
• dfs(w->vertex); }
28/11/2025 School of Computer Engineering, MIT, Manipal 48
Spanning Tree Characteristics:
• Connects all vertices with minimum number of edges
(n – 1 edges).
• Contains no cycles.
• May not be unique — different traversals can produce
different spanning trees.
28/11/2025 School of Computer Engineering, MIT, Manipal 49
A complete graph and three of its spanning tree
28/11/2025 School of Computer Engineering, MIT, Manipal 50