Quiz 2

Week 8: Graph Algorithms — Routes & Paths

2149 words
11 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 8: Graph Algorithms — Routes & Paths > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Week 7 (Graphs, Adjacency Matrices) **Cross-links:** BSCS2002-PDSA (Week 8 — Graph Paths) ## 1. Motivation: Finding Routes Given a train network, how do you find if you can travel from station A to station B?

Week 8: Graph Algorithms — Routes & Paths

BSCS1001 — IIT Madras BS Degree Prerequisite: Week 7 (Graphs, Adjacency Matrices) Cross-links: BSCS2002-PDSA (Week 8 — Graph Paths)

1. Motivation: Finding Routes

Given a train network, how do you find if you can travel from station A to station B?
  • Direct route: One train, no changes
  • One-hop route: Change trains once (A→X→B)
  • Two-hop route: Change trains twice (A→X→Y→B) This is a fundamental graph problem: reachability — which vertices can be reached from which other vertices, and through how many intermediate steps.
Real-world analogy: The "six degrees of separation" — how many introductions do you need to reach any person in the world? That's a multi-hop path in a social network graph.

2. The Train Route Problem

Dataset

Each train has a route: a start station, end station, and (sometimes) intermediate stations.
pseudo
trains = {
    "101": {"start": "Chennai", "end": "Bangalore"},
    "102": {"start": "Bangalore", "end": "Mumbai"},
    "103": {"start": "Chennai", "end": "Mumbai"},
    "104": {"start": "Mumbai", "end": "Delhi"},
    "105": {"start": "Bangalore", "end": "Delhi"}
}

The Problem

Given this network, answer:
  1. Can I go from Chennai to Delhi directly? (A direct train?)
  2. Can I go from Chennai to Delhi with one change? (Chennai→X→Delhi)
  3. What's the shortest route from Chennai to Delhi? (Diagram)

3. Direct Routes

Algorithm

pseudo
Procedure DirectRoutes(trains)
    // Step 1: Collect all unique stations
    stations = {}
    foreach t in keys(trains) {
        stations[trains[t][start]] = True
        stations[trains[t][end]] = True
    }
    // Step 2: Map stations to indices
    n = length(keys(stations))
    stnindex = {}
    i = 0
    foreach s in keys(stations) {
        stnindex[s] = i
        i = i + 1
    }
    // Step 3: Create and populate matrix
    direct = CreateMatrix(n, n)
    foreach t in keys(trains) {
        i = stnindex[trains[t][start]]
        j = stnindex[trains[t][end]]
        direct[i][j] = 1
    }
    return(direct)
End DirectRoutes

Resulting Matrix

For the 4 stations: Chennai(0), Bangalore(1), Mumbai(2), Delhi(3):
pseudo
direct =
        0  1  2  3
     0 [0, 1, 1, 0]    // Chennai → Bangalore, Mumbai
     1 [0, 0, 1, 1]    // Bangalore → Mumbai, Delhi
     2 [0, 0, 0, 1]    // Mumbai → Delhi
     3 [0, 0, 0, 0]    // Delhi → (none)

4. One-Hop Routes

A one-hop route from A to B means: there exists a station K such that:
  • A→K is a direct route (direct[A][K] = 1)
  • K→B is a direct route (direct[K][B] = 1)

Algorithm

pseudo
Procedure WithinOneHop(direct)
    n = length(keys(direct))
    onehop = CreateMatrix(n, n)
    foreach i in rows(direct) {
        foreach j in columns(direct) {
            // First, copy any direct connection
            onehop[i][j] = direct[i][j]
            // Check for one-hop connection via intermediate k
            foreach k in columns(direct) {
                if (direct[i][k] == 1 AND direct[k][j] == 1) {
                    onehop[i][j] = 1
                }
            }
        }
    }
    return(onehop)
End WithinOneHop

How It Works

For each pair (i, j):
  • Check every possible intermediate station k
  • If i connects to k AND k connects to j, then i can reach j in at most 1 hop

Tracing

Direct matrix:
pseudo
    C  B  M  D
C [0, 1, 1, 0]
B [0, 0, 1, 1]
M [0, 0, 0, 1]
D [0, 0, 0, 0]
Computing onehop:
i→jdirect?k candidatesOne-hop via k?onehop[i][j]
C→D0 (no)C→B(1), B→D(1)✅ B connects1
C→M1 (yes)1 (direct)
C→B1 (yes)1 (direct)
B→D1 (yes)1 (direct)
B→?B→M(1), M→D(1)✅ via MB→D already 1
M→?M→D(1), D→?D→? none
Result (onehop):
pseudo
    C  B  M  D
C [0, 1, 1, 1]    // Now Chennai can reach Delhi (via Bangalore or Mumbai)
B [0, 0, 1, 1]
M [0, 0, 0, 1]
D [0, 0, 0, 0]

5. Two-Hop Routes

A two-hop route from A to B means: there exists station K such that:
  • A→K is reachable in at most 1 hop (onehop[A][K] = 1)
  • K→B is a direct route (direct[K][B] = 1)

Algorithm

pseudo
Procedure WithinTwoHops(direct, onehop)
    n = length(keys(direct))
    twohops = CreateMatrix(n, n)
    foreach i in rows(direct) {
        foreach j in columns(direct) {
            // Start with one-hop connections
            twohops[i][j] = onehop[i][j]
            // Check for two-hop connection via intermediate k
            foreach k in columns(direct) {
                if (onehop[i][k] == 1 AND direct[k][j] == 1) {
                    twohops[i][j] = 1
                }
            }
        }
    }
    return(twohops)
End WithinTwoHops

Key Insight

The pattern is: Onemorehop(current, direct) where:
  • We start with current = direct
  • To go "one more hop," check: current[i][k] == 1 AND direct[k][j] == 1

6. N-Hop Routes: Generalization

The General Pattern

pseudo
Procedure OneMoreHop(current, direct)
    n = length(keys(direct))
    result = CreateMatrix(n, n)
    foreach i in rows(direct) {
        foreach j in columns(direct) {
            result[i][j] = current[i][j]
            foreach k in columns(direct) {
                if (current[i][k] == 1 AND direct[k][j] == 1) {
                    result[i][j] = 1
                }
            }
        }
    }
    return(result)
End OneMoreHop

Building Up Iteratively

pseudo
direct = DirectRoutes(trains)
onehop = OneMoreHop(direct, direct)
twohops = OneMoreHop(onehop, direct)
threehops = OneMoreHop(twohops, direct)
// ... and so on

Transitive Closure

The transitive closure of a graph tells us all reachable pairs. We can compute it by repeating OneMoreHop until no new connections are found:
pseudo
reachable = direct
prev = {}
while (reachable ≠ prev) {
    prev = reachable
    reachable = OneMoreHop(reachable, direct)
}

7. Edge-Labelled Graphs

An edge-labelled graph stores additional information on each edge — such as the train name, distance, or travel time.

Representation

Instead of storing just 0/1, each cell in the matrix stores a dictionary of labels:
pseudo
// Create empty dictionaries
foreach r in rows(direct) {
    foreach c in columns(direct) {
        direct[i][j] = {}    // Empty dictionary = no connection
    }
}
// Add edges with labels
foreach t in keys(trains) {
    i = stnindex[trains[t][start]]
    j = stnindex[trains[t][end]]
    direct[i][j][t] = True    // Label with train number
}

Result

pseudo
direct[Chennai][Bangalore] = {"101": True}   // Train 101 connects these
direct[Chennai][Mumbai] = {"103": True}      // Train 103 connects these
If multiple trains connect the same stations:
pseudo
direct[Chennai][Bangalore] = {"101": True, "107": True}   // Two trains!

8. Shortest Distance

Problem

Each train has a distance. Find the shortest path between any two stations.

Direct Distances

pseudo
Procedure DirectDistance(trains)
    // ... create station index ...
    directdist = CreateMatrix(n, n)
    foreach t in keys(trains) {
        i = stn2idx[trains[t][start]]
        j = stn2idx[trains[t][end]]
        if (directdist[i][j] == 0) {
            directdist[i][j] = trains[t][distance]
        }
        else {
            // We already have a route — keep the shorter one
            directdist[i][j] = min(directdist[i][j], trains[t][distance])
        }
    }
    return(directdist)
End DirectDistance

One-Hop Distances

pseudo
Procedure OneHopDistance(directdist)
    n = length(keys(directdist))
    onehopdist = CreateMatrix(n, n)
    foreach i in rows(directdist) {
        foreach j in columns(directdist) {
            onehopdist[i][j] = directdist[i][j]
            foreach k in columns(directdist) {
                if (directdist[i][k] > 0 AND directdist[k][j] > 0) {
                    newdist = directdist[i][k] + directdist[k][j]
                    if (onehopdist[i][j] > 0) {
                        onehopdist[i][j] = min(newdist, onehopdist[i][j])
                    }
                    else {
                        onehopdist[i][j] = newdist
                    }
                }
            }
        }
    }
    return(onehopdist)
End OneHopDistance
This is a simplified version of the Floyd-Warshall algorithm — computing shortest paths between all pairs.

9. Comparison: Route Finding Approaches

AlgorithmWhat It ComputesComplexity
DirectRoutesAll direct connectionsO(T) where T = trains
OneMoreHopOne additional hopO(N³) — triple nested loops
Transitive ClosureAll reachable pairsO(N³ × K) — repeated until stable
Shortest DistanceMinimum path lengthO(N³) — similar to Floyd-Warshall

10. Practice Questions

Basic Questions

Q1. What is a "one-hop route" from station A to station B?
Show Answer
A one-hop route from A to B means there exists an intermediate station K such that:
  • There is a direct train from A to K
  • There is a direct train from K to B
You can travel A→K→B with one change of train. Q2. In the OneMoreHop procedure, what does the condition current[i][k] == 1 AND direct[k][j] == 1 check? Show Answer
It checks whether you can go from i to k using the current reachability matrix, and then from k to j using a direct connection. If both are true, then you can reach j from i with one more hop than before. Q3. What is an edge-labelled graph? Show Answer
An edge-labelled graph stores additional information on each edge. Instead of just a 0/1 in the matrix, each cell stores a dictionary of labels (e.g., train numbers, distances, travel times). Q4. For the direct matrix of 4 stations, how many cells does the matrix have? How many could potentially be 1? Show Answer
The matrix is 4×4 = 16 cells. Without self-loops, the diagonal is always 0. So up to 12 cells could be 1 (all possible directed connections between different stations).

Intermediate Questions

Q5. Trace WithinOneHop for direct matrix:
pseudo
    A  B  C
A [0, 1, 0]
B [0, 0, 1]
C [0, 0, 0]
Show Answer
i→jdirect?k candidatesVia?onehop[i][j]
A→B11
A→C0A→B(1), B→C(1)✅ via B1 (new!)
A→A0A→B(1), B→A(0) → nonone0
B→C11
B→A0nonenone0
C→?0nonenone0
Result:
pseudo
    A  B  C
A [0, 1, 1]    // A→C now possible via B
B [0, 0, 1]
C [0, 0, 0]
Q6. How does OneMoreHop generalize the process of finding longer paths?
Show Answer
OneMoreHop(current, direct) computes connections that are one edge longer than what current represents. By calling it repeatedly:
  • direct = connections of length 1
  • OneMoreHop(direct, direct) = connections of length ≤ 2
  • OneMoreHop(prev, direct) = connections of length ≤ (prev + 1)
This iterative process builds the transitive closure. Q7. In the edge-labelled graph, why do we use a dictionary as the matrix value instead of a list? Show Answer
Using a dictionary allows O(1) lookup to check if a particular label (train number) exists. A list would require scanning to check membership. The dictionary key is the label, and the value is just True. Q8. Write pseudocode to find all stations reachable from Chennai (station index 0) in at most 2 hops. Show Answer
sql
reachable = []
foreach j in columns(twohops) {
    if (twohops[0][j] == 1) {
        reachable = reachable ++ [j]
    }
}
// reachable contains indices of all stations reachable from station 0 in ≤2 hops

Advanced Questions

Q9. How does the shortest distance algorithm differ from the route existence algorithm?
Show Answer
The route existence algorithm (OneMoreHop) checks if a connection exists (boolean). The shortest distance algorithm checks what the minimum distance is (numeric). Key differences:
  1. Initialization: Existence uses 0/1; Distance uses 0/positive numbers
  2. Combination: Existence uses AND; Distance uses addition
  3. Update: Existence sets to 1; Distance uses min() to keep shortest
  4. Check: Existence checks == 1; Distance checks > 0 Q10. Trace OneHopDistance for direct distances:
pseudo
    A   B   C
A [0, 10, 0]
B [0, 0, 20]
C [0, 0, 0 ]
Show Answer
i→jdirect?via knewdistonehopdist[i][j]
A→B1010
A→C0A→B(10), B→C(20)10+20=3030
A→A0none0
B→C2020
B→A0none0
C→?0none0
Result: A→C = 30 (via B) Q11. Explain the relationship between route finding and matrix multiplication. Show Answer
The OneMoreHop operation is essentially boolean matrix multiplication:
  • Route existence: result[i][j] = OR over k of (current[i][k] AND direct[k][j])
  • This is the same as: result = current × direct (with AND as multiplication, OR as addition)
The shortest distance variant is analogous to min-plus matrix multiplication:
  • result[i][j] = MIN over k of (current[i][k] + direct[k][j])
  • This is the Floyd-Warshall algorithm.
So route finding is just matrix multiplication in disguise! Q12. Design an algorithm to find if there is a cycle in a directed graph (a path from a station back to itself through other stations). Show Answer
pseudo
Procedure HasCycle(direct)
    n = length(keys(direct))

    // Compute transitive closure
    reachable = direct
    changed = True
    while (changed) {
        changed = False
        newReachable = OneMoreHop(reachable, direct)
        if (newReachable ≠ reachable) {
            changed = True
        }
        reachable = newReachable
    }

    // Check if any station can reach itself (except self-loop = 0)
    foreach i in rows(reachable) {
        if (reachable[i][i] == 1) {
            return(True)    // Cycle exists!
        }
    }

    return(False)
End HasCycle
A cycle exists if, after computing transitive closure, any diagonal element is 1.

📚 Cross-References

CourseTopicConnection
BSCS2002 (PDSA)Week 8 — Graph algorithmsPath finding, Floyd-Warshall
BSCS2002 (PDSA)Week 7 — Graph representationsAdjacency matrix

Next Topic: 15 — Recursion
Quiz Tip: One-hop and two-hop routing questions are common in the End Term. Practice the trace pattern! Join Discord PreviousAdjacency MatricesNextRecursion
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.