Graph Algorithms Study Guide
Graph Algorithms Study Guide
Introduction
Purpose: This guide provides a comprehensive resource for mastering graph
algorithms, specifically tailored for tackling challenges encountered in FAANG
software engineering interviews. The objective is to build a deep, intuitive
understanding and practical proficiency, enabling confident problem-solving for any
graph-related question.
Scope: The study guide covers the essential spectrum of graph theory relevant to
technical interviews. It begins with fundamental concepts like graph definitions and
representations, progresses through core traversal techniques (BFS and DFS), delves
into shortest path algorithms (Dijkstra, Bellman-Ford, Floyd-Warshall), explores
Minimum Spanning Trees (Prim's, Kruskal's), and examines topological sorting, cycle
detection, connectivity analysis (including Strongly Connected Components), and the
crucial Union-Find data structure.
Approach: The focus is on building intuition – understanding the "why" behind each
algorithm's steps and its underlying assumptions. This is complemented by clear,
standard C++ implementations designed for readability and interview contexts.
Complexity analysis (time and space) is provided for each algorithm, a critical aspect
of interview discussions. Finally, curated practice problems from LeetCode,
prioritizing those likely encountered in FAANG interviews, are mapped to relevant
algorithms to solidify understanding and application skills.
I. Graph Fundamentals
A. Core Concepts
Graphs are mathematical structures used to model pairwise relationships between
objects.1 They are fundamental in computer science, representing diverse systems
like social networks, road maps, computer networks, and dependencies.3 Formally, a
graph G is defined as an ordered pair G = (V, E), where V is a set of vertices (also
called nodes or points) representing the entities, and E is a set of edges (also called
links or arcs) representing the connections or relationships between these vertices.1
● Vertices (Nodes): These are the basic units of a graph, often depicted as circles
or points. Each vertex typically represents an object, entity, or location.1
● Edges (Links): These represent the connections or relationships between pairs
of vertices, usually drawn as lines.1 An edge connecting vertices u and v can be
denoted as (u, v) or {u, v}.
B. Graph Representations
To work with graphs computationally, we need ways to represent their structure in
memory. The two most common methods are the Adjacency Matrix and the
Adjacency List.3
1. Adjacency Matrix:
● Definition: An adjacency matrix represents a graph G = (V, E) as a V x V square
matrix (let's call it adjMat), where V is the number of vertices. The entry adjMat[i]
[j] is typically 1 (or the edge weight for weighted graphs) if there is an edge from
vertex i to vertex j, and 0 otherwise.3 For undirected graphs, the adjacency matrix
is symmetric (adjMat[i][j] == adjMat[j][i]) because an edge {i, j} implies
connections in both directions.4 For weighted graphs, non-edge entries are often
initialized to infinity (or a very large number) and diagonal entries (adjMat[i][i])
are 0.16
● C++ Implementation: A common way to implement this in C++ is using a vector
of vectors: vector<vector<int>> adjMatrix(V, vector<int>(V, 0)); for an unweighted
graph, or vector<vector<int>> adjMatrix(V, vector<int>(V, INF)); for a weighted
graph (initializing diagonals to 0 separately). Adding an edge (u, v) with weight w
involves adjMatrix[u][v] = w; (and adjMatrix[v][u] = w; if undirected).12 While
simple, vector<vector<int>> can have performance drawbacks due to multiple
memory allocations and potentially poor cache locality.14 Using a single
std::vector<int> data(V*V); and indexing with data[i * V + j] offers better memory
contiguity.14 C++23's std::mdspan provides a safer and more expressive way to
view this single vector as a 2D matrix.14 However, for typical interview settings,
vector<vector<int>> is often sufficient and understood.
#include <vector>
#include <iostream>
/* Example demonstration:
int main() {
int V = 5; // Number of vertices in the graph.
// Initialize a V x V matrix with all elements set to 0.
vector<vector<int>> adjMatrix(V, vector<int>(V, 0));
2. Adjacency List:
● Definition: An adjacency list represents a graph as an array (or vector) of lists (or
vectors, sets). The element at index i in the array, adjList[i], contains a list of all
vertices adjacent to vertex i.3 For weighted graphs, the list stores pairs of
{neighbor, weight}.16
● C++ Implementation: Typically implemented using std::vector<std::vector<int>>
for unweighted graphs or std::vector<std::vector<std::pair<int, int>>> for
weighted graphs. Adding an edge (u, v) with weight w involves
adjList[u].push_back({v, w}); (and adjList[v].push_back({u, w}); if undirected).12
While std::list can also be used (vector<list<pair<int, int>>>), vector often provides
better cache performance in C++ due to contiguous memory allocation for
elements within each inner vector, even though insertions/deletions in the middle
are slower than lists.38 Some competitive programming contexts use C-style
arrays of vectors (vector<int> adj[V];), but vector<vector<int>> is generally
preferred in modern C++ for safety and flexibility.29
#include <vector>
#include <list>
#include <utility>
#include <iostream>
/* Example Usage:
int main() {
int V = 5; // Number of vertices in the graph.
AdjacencyList adjList(V); // Initialize the adjacency list with V
vertices.
● Pros:
○ Space Efficiency: Space complexity is O(V + E), which is much better than
O(V^2) for sparse graphs.3
○ Efficient Neighbor Iteration: Iterating through all neighbors of a vertex u
takes O(degree(u)) time, which is efficient for traversal algorithms.20 Total
time for iterating all neighbors across all vertices is O(V+E).
○ Efficient Edge/Node Addition: Adding an edge is typically O(1) (amortized
for vector).20 Adding a node is also efficient.20
● Cons:
○ Slower Edge Checking: Checking if a specific edge (u, v) exists requires
searching u's adjacency list, taking O(degree(u)) time in the worst case.20
○ Slower Edge Removal: Removing an edge (u, v) requires finding v in u's list
(and u in v's list if undirected), which takes O(degree(u)) or O(degree(v))
time.21
3. Edge List:
● Definition: A simple list or array containing tuples or objects representing each
edge, often as (u, v, weight).4
● Complexity: Space complexity is O(E).3
● Use Cases: Useful when the primary task is to iterate over all edges (e.g.,
Kruskal's algorithm) or for simple graph input formats. Less efficient for
algorithms requiring frequent neighbor lookups (like BFS/DFS).9
The key factors are the graph's density and the dominant operations needed.
● Density: If the graph is sparse (number of edges E is much smaller than the
maximum possible, V^2, often closer to O(V)), the O(V^2) space complexity of an
adjacency matrix becomes prohibitive. Adjacency lists, requiring only O(V + E)
space, are far more memory-efficient.3 Conversely, for dense graphs (E
approaches V^2), the O(V^2) space of the matrix is comparable to the O(V + E) ≈
O(V^2) space of the list, making space less of a deciding factor.10
● Operations: If the algorithm primarily involves iterating over neighbors of
nodes (like BFS, DFS, Dijkstra's, Prim's), adjacency lists are superior. Finding
neighbors takes O(degree) time per node, leading to efficient O(V+E) overall
traversal times.20 Adjacency matrices require O(V) time to find neighbors,
resulting in slower O(V^2) traversals.20 However, if the main operation is
checking for the existence of a specific edge (u, v) or quickly
adding/removing edges, the O(1) performance of an adjacency matrix is
advantageous compared to the O(degree(u)) lookup time for an adjacency list.9
#include <vector>
#include <queue>
#include <iostream>
return 0;
}
*/
● Complexity Analysis:
○ Time: O(V + E). Each vertex is enqueued and dequeued exactly once (O(V)).
Each edge (u, v) is examined exactly twice in an undirected graph (once from
u, once from v) or once in a directed graph when iterating through neighbors
(O(E)). Thus, the total time is proportional to V + E.3 If using an adjacency
matrix, finding neighbors takes O(V) for each node, leading to O(V^2) time
complexity.27
○ Space: O(V). The space is required for the visited array (O(V)) and the queue.
In the worst case (e.g., a star graph), the queue might hold up to O(V)
nodes.27
● Applications:
○ Shortest Path in Unweighted Graphs: BFS inherently finds the shortest
path in terms of the number of edges from the source node to all other
reachable nodes.3 This is because it explores level by level, guaranteeing that
the first time a node is reached, it is via a path with the minimum possible
number of edges.
○ Level Order Traversal: Directly performs level order traversal of trees or
graphs.36
○ Connectivity: Finding connected components in undirected graphs.3
Running BFS from an unvisited node finds all nodes in its component.
○ Cycle Detection (Undirected): Can detect cycles in undirected graphs by
checking if a visited node (that is not the immediate parent) is encountered.40
○ Bipartite Graph Check: Can be used to check if a graph is bipartite by
attempting a 2-coloring during traversal.51
○ Other: Network broadcasting, web crawling, finding neighbor nodes in P2P
networks, GPS navigation (finding nearby locations).27
Practice Problems:
#include <vector>
#include <stack>
#include <iostream>
#include <algorithm> // For reverse
return 0;
}
*/
● Complexity Analysis:
○ Time: O(V + E). Similar to BFS, each vertex is visited once, and each edge is
considered once (directed) or twice (undirected).3 If using an adjacency
matrix, it becomes O(V^2).28
○ Space: O(V). Space is needed for the visited array. Additionally, space is
required for the call stack in the recursive version or the explicit stack in the
iterative version. In the worst case (e.g., a long path graph), the stack depth
can reach O(V).28
● Applications:
○ Cycle Detection: Very effective for detecting cycles in both directed (using
colors/states) and undirected graphs (using parent tracking).3
○ Topological Sorting: The reverse order of finishing times in a DFS traversal
of a DAG yields a topological sort.3
○ Connectivity: Finding connected components (undirected) and strongly
connected components (directed - Kosaraju's, Tarjan's algorithms are DFS-
based).3
○ Pathfinding & Maze Solving: Exploring paths, though not guaranteed to find
the shortest path in general graphs.28
○ Backtracking: The recursive nature is ideal for problems requiring exhaustive
search and backtracking.28 Examples include solving puzzles like Sudoku or N-
Queens (though often modeled implicitly as state graphs).
Practice Problems :
1. Number of Islands
2. Number of Provinces
3. Max Area of Island
4. Surrounded Regions
5. Pacific Atlantic Water Flow
6. Clone Graph
7. Longest Increasing Path in a Matrix
8. Word Search
9. Word Search II
10. Number of Connected Components in an Undirected Graph
11. Graph Valid Tree
12. Course Schedule (Cycle Detection)
13. Course Schedule II (Topological Sort)
14. Find Eventual Safe States (Related to Cycle Detection)
15. Minimum Height Trees (Utilizing Breadth-First Search/Depth-First Search on
Tree-like Structures)
A. Introduction
● Problem Definition: Given a weighted graph G = (V, E), find a path between two
vertices (or from a single source to all other vertices, or between all pairs of
vertices) such that the sum of the weights of the edges in the path is minimized.57
● Variations:
○ Single-Source Shortest Path (SSSP): Find shortest paths from a designated
source vertex s to all other vertices.51 Dijkstra and Bellman-Ford solve this.
BFS solves the unweighted version.
○ All-Pairs Shortest Path (APSP): Find the shortest path between every pair
of vertices in the graph.17 Floyd-Warshall solves this. Alternatively, run an
SSSP algorithm from each vertex.
● Edge Weight Significance:
○ Unweighted: All edge weights are 1. BFS is the most efficient algorithm.27
○ Non-Negative Weights: Edge weights are >= 0. Dijkstra's algorithm is
typically the most efficient.3
○ Negative Weights Allowed (No Negative Cycles): Edge weights can be
negative, but no cycle exists where the sum of edge weights is negative.
Bellman-Ford works; Dijkstra does not.51 Floyd-Warshall also works for
APSP.114
○ Negative Cycles: If a negative cycle is reachable from the source, the
shortest path is undefined (can be made arbitrarily small by traversing the
cycle). Bellman-Ford and Floyd-Warshall can detect negative cycles.51
B. Dijkstra's Algorithm
● Concept: A greedy algorithm that finds the shortest paths from a single source
vertex s to all other vertices in a weighted graph where all edge weights are non-
negative.3 It maintains a set of visited vertices for which the shortest path is
known and iteratively adds the "closest" unvisited vertex to this set.
● Mechanism:
1. Initialize distances: dist[s] = 0, and dist[v] = infinity for all other vertices v.
2. Maintain a set (or priority queue) Q of vertices not yet finalized. Initially, Q
contains all vertices.
3. While Q is not empty: a. Select the vertex u in Q with the minimum dist[u]
value. b. Remove u from Q (mark as finalized/visited). c. For each neighbor v
of u: Perform relaxation. If dist[u] + weight(u, v) < dist[v], update dist[v] =
dist[u] + weight(u, v).4 If using a priority queue, add/update v with its new
distance.
● Why Non-Negative Weights are Crucial: Dijkstra's algorithm relies on the
greedy choice: once a vertex u is extracted as the minimum distance vertex from
Q, its dist[u] is considered the final shortest path distance. This holds true only if
edge weights are non-negative. If a negative edge existed elsewhere, a path
going through that edge might later reveal a shorter path to u after u has already
been finalized, violating the algorithm's core assumption.51
● Data Structure Choice: A min-priority queue is the standard data structure for
efficiently implementing step 3a (extracting the minimum distance vertex).3 C++'s
std::priority_queue doesn't directly support the "decrease-key" operation often
mentioned in theoretical descriptions. The common workaround is to simply
insert the vertex with its new, smaller distance into the priority queue, allowing
duplicates. When extracting elements, check if the extracted distance matches
the current best known distance; if not, it's a stale entry and should be ignored.32
std::set<pair<int, int>> can also be used, offering logarithmic time for finding the
minimum, removing, and inserting, effectively simulating decrease-key.32
priority_queue often has better constant factors.32
● C++ Implementation (Priority Queue):
#include <vector>
#include <queue>
#include <utility> // For std::pair
#include <limits> // For numeric_limits
while (!priorityQueue.empty()) {
// Extract the vertex with the minimal distance value
int currentDistance = priorityQueue.top().first;
int currentVertex = priorityQueue.top().second;
priorityQueue.pop();
// Optimization: If the extracted entry is outdated, proceed
to the next entry
if (currentDistance > distance[currentVertex]) {
continue;
}
/* Example Usage:
int main() {
int numberOfVertices = 5;
vector<vector<pair<int, int>>> adjacencyList(numberOfVertices);
// Populate the adjacency list with edges using
addEdgeList(adjacencyList, u, v, weight);
// Note: Dijkstra's algorithm requires only one direction in the
adjacency list for directed graphs
// Example graph (undirected, add both directions or adapt the
algorithm):
adjacencyList.push_back({1, 4}); adjacencyList.push_back({0, 4});
adjacencyList.push_back({2, 8}); adjacencyList.push_back({0, 8});
adjacencyList.push_back({4, 6}); adjacencyList.push_back({1, 6});
adjacencyList.push_back({3, 2}); adjacencyList.push_back({2, 2});
adjacencyList.push_back({4, 10}); adjacencyList.push_back({3,
10});
int sourceVertex = 0;
vector<int> shortestDistances =
calculateShortestPaths(numberOfVertices, adjacencyList, sourceVertex);
cout << "Vertex Distance from Source " << sourceVertex << endl;
for (int i = 0; i < numberOfVertices; ++i)
cout << i << "\t\t" << (shortestDistances[i] == INFINITY ?
"INF" : to_string(shortestDistances[i])) << endl;
// Expected Output (for source 0): 0: 0, 1: 4, 2: 8, 3: 10, 4: 10
return 0;
}
*/
● Complexity Analysis:
○ Time: O(E log V) or O((V + E) log V) using a binary heap (priority queue). Each
vertex is added/extracted once (O(V log V)). Each edge relaxation might lead
to adding a new element to the priority queue (O(E log V)).3
○ Space: O(V + E) for storing the graph (adjacency list), the distance array, and
the priority queue (which can hold up to O(E) elements in the duplicate-entry
implementation, but O(E) <= O(V^2), and log E is O(log V)).109
● Practice Problems:
1. Network Delay Time
2. Path With Minimum Effort
3. Minimum Obstacle Removal to Reach Corner
4. Number of Ways to Arrive at Destination (Path Tracking Required)
5. Minimum Time to Visit a Cell In a Grid
6. Shortest Path in Binary Matrix (Consider Dijkstra's Algorithm for Non-Uniform
Weights)
7. Find the Safest Path in a Grid (Involves Binary Search and Graph Traversal
Algorithms)
Supplementary Material: LeetCode 1514. Path with Maximum Probability (Utilize a modified
Dijkstra's Algorithm for Probability Optimization).
C. Bellman-Ford Algorithm
● Concept: A more general SSSP algorithm that can handle negative edge
weights, unlike Dijkstra's.51 It is also capable of detecting negative cycles
reachable from the source.
● Mechanism: The core idea is based on the principle of relaxation. It repeatedly
relaxes all edges in the graph. If a graph with V vertices has no negative cycles,
the shortest path from the source to any other vertex can have at most V-1
edges.115 Bellman-Ford leverages this by performing V-1 passes of relaxing every
edge in the graph.51
1. Initialize distances: dist[s] = 0, dist[v] = infinity for all other v.
2. Repeat V-1 times: For each edge (u, v) with weight w: Relax the edge: if
dist[u] + w < dist[v], then update dist[v] = dist[u] + w.
3. Negative Cycle Detection: After V-1 passes, perform one additional pass
through all edges. If any distance dist[v] can still be improved (i.e., dist[u] + w
< dist[v] for some edge (u, v)), then a negative cycle reachable from the
source exists.51 In such cases, shortest paths are ill-defined (can be infinitely
small).
● Why V-1 Relaxations Suffice (No Negative Cycles): Any simple shortest path
(without cycles) contains at most V-1 edges. In the first pass, Bellman-Ford finds
shortest paths using at most 1 edge. In the second pass, it finds shortest paths
using at most 2 edges (by potentially extending the 1-edge paths found in pass
1), and so on. After k passes, the algorithm guarantees finding the shortest paths
that use at most k edges.115 Therefore, after V-1 passes, it must have found the
shortest simple paths.115 If a distance can be further reduced in the V-th pass, it
implies the shortest path requires V or more edges, which is only possible if it
involves traversing a negative cycle.113
● C++ Implementation (Edge List): Bellman-Ford is often implemented using a
simple list of edges, as it needs to iterate through all edges repeatedly.
#include <vector>
#include <limits>
#include <iostream>
using std::vector;
using std::cout;
using std::endl;
using std::numeric_limits;
using std::string;
struct Edge {
int sourceVertex;
int destinationVertex;
int weight;
};
/* Example Usage:
int main() {
int numberOfVertices = 5;
vector<Edge> edges = {
{0, 1, -1}, {0, 2, 4}, {1, 2, 3},
{1, 3, 2}, {1, 4, 2}, {3, 2, 5},
{3, 1, 1}, {4, 3, -3}
// Example with a negative cycle: {0,1,1}, {1,2,-1}, {2,0,-1}
};
int source = 0;
vector<long long> shortestDistances;
bool hasNegativeCycle =
detectNegativeCycleAndCalculateShortestDistances(numberOfVertices,
edges, source, shortestDistances);
if (hasNegativeCycle) {
cout << "Graph contains a negative cycle reachable from source
" << source << endl;
} else {
cout << "Vertex Distance from Source " << source << endl;
for (int i = 0; i < numberOfVertices; ++i) {
cout << i << "\t\t"
<< (shortestDistances[i] == INFINITY_VALUE ? "INF" :
(shortestDistances[i] == -INFINITY_VALUE ? "-INF"
: std::to_string(shortestDistances[i])))
<< endl;
}
// Expected Output (for source 0, no neg cycle example):
// 0: 0, 1: -1, 2: 2, 3: -2, 4: 1
}
return 0;
}
*/
● Complexity Analysis:
○ Time: O(V * E). The algorithm consists of V passes, and each pass iterates
through all E edges.60
○ Space: O(V) to store the distances. O(E) if storing edges explicitly.114
● Practice Problems:
● Cheapest Flights Within K Stops (Can be adapted from Bellman-Ford by
limiting passes to K) 72
● Supplement: Problems explicitly involving negative edge weights or requiring
negative cycle detection (e.g., arbitrage detection). CSES Problem Set:
Shortest Routes II (requires negative cycle check).
D. Floyd-Warshall Algorithm
● Concept: An algorithm for finding the shortest paths between all pairs of
vertices (APSP) in a weighted graph.17 It uses dynamic programming.114 It can
handle negative edge weights, but like Bellman-Ford, it assumes there are no
negative cycles.114
● Mechanism: It works by iteratively considering each vertex k as a potential
intermediate vertex on the shortest path between any two vertices i and j. It
updates the distance dist[i][j] if the path from i to j through k (dist[i][k] + dist[k]
[j]) is shorter than the current known shortest path dist[i][j].17
1. Initialize a distance matrix dist[V][V]. dist[i][j] is the weight of the direct edge
(i, j) if it exists, 0 if i == j, and infinity otherwise.
2. Use three nested loops: for k from 0 to V-1, for i from 0 to V-1, for j from 0 to
V-1.
3. Inside the innermost loop, apply the update rule: dist[i][j] = min(dist[i][j],
dist[i][k] + dist[k][j]).17
4. After the loops complete, dist[i][j] holds the shortest path distance from i to j.
● Why k Must Be the Outer Loop: The order k, i, j is essential. When the outer
loop is at iteration k, the algorithm computes the shortest paths between all pairs
(i, j) considering only intermediate vertices from the set {0, 1,..., k}. For this
computation to be correct, the values dist[i][k] and dist[k][j] must represent the
shortest paths using only intermediate vertices from {0, 1,..., k-1}, which are
guaranteed to have been computed in the previous iterations of the outer k loop.
If k were an inner loop, this subproblem optimality wouldn't hold.120
● Negative Cycle Detection: After the algorithm runs, if any diagonal element
dist[i][i] is negative, it indicates that vertex i is part of or can reach a negative
cycle.120
● C++ Implementation:
#include <vector>
#include <algorithm> // For std::min
#include <limits> // For numeric_limits
#include <iostream>
/**
* Implements the Floyd-Warshall algorithm to find the shortest paths
between all pairs of vertices in a graph.
*
* @param numVertices The number of vertices in the graph.
* @param distanceMatrix A 2D vector representing the initial distance
matrix, where:
* - distanceMatrix[i][j] = weight(i, j) if an
edge exists between vertices i and j.
* - distanceMatrix[i][i] = 0.
* - distanceMatrix[i][j] = INFINITY_VALUE if no
direct edge exists between vertices i and j.
*/
void floydWarshall(int numVertices, vector<vector<int>>&
distanceMatrix) {
for (int k = 0; k < numVertices; ++k) {
for (int i = 0; i < numVertices; ++i) {
for (int j = 0; j < numVertices; ++j) {
if (distanceMatrix[i][k] != INFINITY_VALUE &&
distanceMatrix[k][j] != INFINITY_VALUE &&
distanceMatrix[i][j] > distanceMatrix[i][k] +
distanceMatrix[k][j]) {
distanceMatrix[i][j] = distanceMatrix[i][k] +
distanceMatrix[k][j];
}
}
}
}
/* Example Demonstration:
int main() {
int numVertices = 4;
// Initialization of distance matrix based on direct edges
vector<vector<int>> distanceMatrix = {
{0, 5, INFINITY_VALUE, 10},
{INFINITY_VALUE, 0, 3, INFINITY_VALUE},
{INFINITY_VALUE, INFINITY_VALUE, 0, 1},
{INFINITY_VALUE, INFINITY_VALUE, INFINITY_VALUE, 0}
};
floydWarshall(numVertices, distanceMatrix);
return 0;
}
*/
● Complexity Analysis:
○ Time: O(V^3). The three nested loops iterating up to V dominate the
runtime.114
○ Space: O(V^2) to store the distance matrix.114
● Practice Problems:
● Find the City With the Smallest Number of Neighbors at a Threshold Distance 72
● Supplement: LeetCode 399. Evaluate Division (Can be solved via APSP).
Problems where APSP is needed and V is small enough (e.g., V <= ~400).
27
B. Prim's Algorithm
● Concept: A greedy algorithm that builds the MST incrementally, starting from an
arbitrary vertex.3 It maintains a set of vertices already included in the MST. In
each step, it adds the minimum-weight edge that connects a vertex inside the
current MST to a vertex outside the MST.140 This process continues until all
vertices are included.
● Mechanism:
1. Initialize: Create a set mstSet (or visited array) to track vertices in the MST,
initially empty. Create a key array to store the minimum edge weight
connecting each vertex v to the MST (key[v]), initialized to infinity for all v
except the start vertex s (key[s] = 0). Optionally, maintain a parent array to
reconstruct the MST edges.
2. Use a min-priority queue pq storing pairs {key[v], v}. Initialize pq with {0,
s}.140
3. While pq is not empty: a. Extract the vertex u with the minimum key from pq.
b. If u is already in mstSet (visited), continue (skip stale entries). c. Add u to
mstSet. Add the edge connecting u to its parent (if tracked) to the MST
result. d. For each neighbor v of u: If v is not in mstSet and the edge weight
weight(u, v) is less than key[v]: Update key[v] = weight(u, v). Update the
parent of v to u. Add {key[v], v} to pq (or perform decrease-key if the priority
queue supports it).
● C++ Implementation (Priority Queue):
#include <vector>
#include <queue>
#include <utility> // For std::pair
#include <limits> // For numeric_limits
int mstWeightSum = 0;
while (!pq.empty()) {
// Extract vertex u possessing the minimum key value
int u = pq.top().second;
int u_key = pq.top().first; // Obtain the key associated with
u
pq.pop();
return mstWeightSum;
}
/* Example Usage:
int main() {
int V = 5;
vector<vector<pair<int, int>>> adj(V);
// Procedure to add undirected edges
auto addEdgePrim = [&](int u, int v, int w){
adj[u].push_back({v, w});
adj[v].push_back({u, w});
};
addEdgePrim(0, 1, 2);
addEdgePrim(0, 3, 6);
addEdgePrim(1, 2, 3);
addEdgePrim(1, 3, 8);
addEdgePrim(1, 4, 5);
addEdgePrim(2, 4, 7);
addEdgePrim(3, 4, 9);
return 0;
}
*/
● Complexity Analysis:
○ Time: O(E log V) or O((V + E) log V) using a binary heap (priority queue).
Extracting the minimum V times takes O(V log V). Each edge might lead to a
decrease-key operation (or insertion in the common C++ implementation),
totaling O(E log V).3 The dominant term is usually O(E log V).
○ Space: O(V + E) for the adjacency list, priority queue, key array, and visited
array.158
● Practice Problems:
● Min Cost to Connect All Points 118
● Supplement: LeetCode 1135. Connecting Cities With Minimum Cost.
C. Kruskal's Algorithm
● Concept: Another greedy algorithm for finding the MST. It operates by
considering edges in increasing order of weight and adding an edge to the
growing MST (initially empty) if and only if adding the edge does not form a
cycle.3
● Mechanism:
1. Create a list of all edges (u, v, weight) in the graph.
2. Sort the edges in non-decreasing order of their weights.139
3. Initialize an empty set MST to store the edges of the minimum spanning tree.
4. Initialize a Union-Find (Disjoint Set Union - DSU) data structure with V
disjoint sets, one for each vertex.74
5. Iterate through the sorted edges (u, v, weight): a. Check if vertices u and v
are already in the same component using the DSU's find operation (find(u)!=
find(v)). b. If they are in different components (i.e., adding the edge does not
create a cycle): Add the edge (u, v, weight) to MST. Merge the components of
u and v using the DSU's union operation (union(u, v)).139
6. Stop when MST contains V-1 edges (or when all edges have been processed).
● Data Structures: Requires sorting the edges and an efficient Union-Find data
structure (with path compression and union by rank/size optimizations) for cycle
detection.74
● C++ Implementation:
#include <vector>
#include <numeric> // For std::iota
#include <algorithm> // For std::sort
#include <iostream>
struct Edge {
int u, v, weight;
// Comparator for sorting edges by weight
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
DisjointSet(int n) {
parent.resize(n);
iota(parent.begin(), parent.end(), 0); // Initialize parent[i]
= i
rank.assign(n, 0); // Initialize rank of all nodes to 0
}
int find(int i) {
if (parent[i] == i)
return i;
// Path Compression
return parent[i] = find(parent[i]);
}
DisjointSet disjointSet(V);
int minimumSpanningTreeWeight = 0;
int edgesInTree = 0;
vector<Edge> minimumSpanningTreeEdges; // Optional: to store MST
edges
return minimumSpanningTreeWeight;
}
● Complexity Analysis:
○ Time: O(E log E) or O(E log V). Sorting the E edges takes O(E log E) time. The
subsequent loop iterates through E edges, performing two find operations
and potentially one union operation per edge. With optimized DSU, these
operations take nearly constant amortized time, O(α(V)). Thus, the total time
is dominated by the sorting step: O(E log E + E α(V)) ≈ O(E log E).3 Since E can
be up to O(V^2), log E can be up to O(log V^2) = O(2 log V) = O(log V), so O(E
log E) is often written as O(E log V).
○ Space: O(V + E) to store the graph edges and the DSU data structure.167
● Kruskal's vs. Prim's: Kruskal's algorithm's complexity is dominated by edge
sorting, making it potentially more efficient for sparse graphs (where E is closer
to V) compared to Prim's O(E log V) if E is significantly less than V^2.150 Prim's
algorithm might be preferred for dense graphs (E approaches V^2) as its O(E log
V) complexity might outperform O(E log E) in some scenarios, especially with
more advanced heap structures like Fibonacci heaps (O(E + V log V)).150 Kruskal's
processes edges globally based on weight, while Prim's grows the MST locally
from a starting vertex. Kruskal's use of Union-Find naturally connects it to
problems involving component merging and cycle detection.
● Practice Problems:
● Min Cost to Connect All Points 118
● The Earliest Moment When Everyone Become Friends (DSU application, related
logic)
● Supplement: LeetCode 1168. Optimize Water Distribution in a Village.74
LeetCode 1489. Find Critical and Pseudo-Critical Edges in Minimum Spanning
Tree.74
Time Complexity O(E log V) (with binary heap) O(E log E) or O(E log V) (sort
dominates)
Best For Generally better for Dense Generally better for Sparse
Graphs Graphs
Works cited
Topological sorting finds applications in various domains where tasks or events have
prerequisite relationships 4:
● Task Scheduling: Ordering jobs or tasks where certain tasks must be completed
before others can begin (e.g., build systems, project management).4
● Course Scheduling: Determining a valid sequence for taking courses with
prerequisites.5
● Dependency Resolution: Resolving dependencies in software package
management or module loading.5
● Compiler Instruction Scheduling: Ordering instructions while respecting data
dependencies.11
● Data Serialization: Determining the order to serialize objects with
interdependencies.11
● Spreadsheet Cell Evaluation: Calculating cell values based on dependencies on
other cells.
Essentially, any problem that can be modeled as a DAG with precedence constraints
can potentially benefit from topological sorting.11
C++ Implementation:
#include <vector>
#include <queue>
● Complexity Analysis:
○ Time Complexity: O(V + E). Calculating initial in-degrees involves iterating
through all edges (O(E)) and vertices (O(V)). Initializing the queue takes O(V).
The main while loop processes each vertex and each edge exactly once.
Enqueue and dequeue operations take O(1) amortized time. Therefore, the
total time complexity is dominated by scanning vertices and edges, resulting
in O(V + E).7
○ Space Complexity: O(V + E) or O(V). Storing the adjacency list requires O(V
+ E) space. The in_degree array requires O(V) space. The queue can hold up
to O(V) vertices in the worst case. The result vector also requires O(V) space.
Thus, the auxiliary space complexity (beyond the input graph representation)
is O(V).12 If considering the adjacency list as part of the input, the total space
is O(V + E).
C++ Implementation:
#include <vector>
#include <stack>
#include <algorithm> // For std::reverse (if using vector instead of
stack)
std::vector<int> result;
// Retrieve the topological order by popping vertices from the
stack.
while (!st.empty()) {
result.push_back(st.top());
st.pop();
}
● Complexity Analysis:
○ Time Complexity: O(V + E). The DFS algorithm visits each vertex and
traverses each edge exactly once.1 Pushing V elements onto the stack and
popping them takes O(V) time. Thus, the overall complexity is O(V + E).
○ Space Complexity: O(V + E) or O(V). Storing the adjacency list requires O(V
+ E). The visited array requires O(V). The stack (or result vector) requires
O(V). The depth of the recursion stack can reach O(V) in the worst case (e.g.,
a long chain). Therefore, the auxiliary space complexity is O(V).1
2.1 Concept
● Undirected Cycle: A path in an undirected graph starting and ending at the
same vertex, using distinct edges (and typically distinct intermediate vertices).28
● Directed Cycle: A path in a directed graph that follows the direction of the
edges and returns to the starting vertex.28
C++ Implementation:
#include <vector>
#include <vector>
● Complexity Analysis:
○ Time: O(V + E). Standard DFS complexity.40
○ Space: O(V). For the visited array and recursion stack.40
#include <vector>
#include <queue>
#include <vector>
#include <utility> // For std::pair
visited[start_node] = true;
q.push({start_node, -1}); // The start node has no parent,
represented by -1.
while (!q.empty()) {
int u = q.front().first;
int parent = q.front().second;
q.pop();
40
● Complexity Analysis:
○ Time: O(V + E). Standard BFS complexity.40
○ Space: O(V). For the visited array and the queue (which can hold up to O(V)
nodes in the worst case).40
#include <vector>
#include <numeric> // For std::iota
#include <utility> // For std::pair, std::swap
DSU(int n) {... }
int find(int i) {... }
void uniteByRank(int i, int j) {... }
// Or void uniteBySize(int i, int j) {... }
};
*/
45
● Complexity Analysis:
○ Time: O(E * α(V)). Initializing the DSU takes O(V). Processing each of the E
edges involves two find operations and potentially one union operation. With
path compression and union by rank/size optimizations, these operations take
O(α(V)) amortized time, where α is the extremely slow-growing inverse
Ackermann function. Thus, the total time is O(V + E * α(V)), which is nearly
linear in E for practical purposes.45
○ Space: O(V). Required to store the parent and rank (or size) arrays for the
DSU structure.45
Section 3: Connectivity
Connectivity explores how vertices are connected within a graph. The concept differs
slightly between undirected and directed graphs.
3.1 Concept
● Undirected Graphs - Connected Components: A connected component is a
maximal subgraph where any two vertices are reachable from each other via
some path. An undirected graph can be partitioned into one or more disjoint
connected components. If a graph has only one connected component, it is
called a connected graph.67
● Directed Graphs - Strongly Connected Components (SCCs): An SCC is a
maximal subgraph where for any two vertices u and v within the subgraph, there
exists a directed path from u to v and a directed path from v to u. Every vertex in
a directed graph belongs to exactly one SCC (which could be a single vertex if it's
not part of a larger strongly connected structure).76
● Condensation Graph: If each SCC in a directed graph G is contracted into a
single "meta-node", the resulting graph of SCCs (with edges representing
connections between components in G) is always a Directed Acyclic Graph
(DAG).27
#include <vector>
#include <numeric> // For std::iota
● Complexity Analysis:
○ Time: O(V + E) for BFS/DFS using adjacency lists.69 O(V + E * α(V)) for Union-
Find.71
○ Space: O(V) auxiliary space for BFS/DFS (visited array, queue/recursion
stack).69 O(V) for Union-Find (parent/rank arrays).71
#include <vector>
#include <stack>
#include <vector>
#include <algorithm> // For std::fill
while (!st.empty()) {
int u = st.top();
st.pop();
79
4.2 Optimizations
The naive implementation can be very inefficient due to the potential formation of tall,
skinny trees during union operations, leading to linear time complexity for find.112 Two
standard optimizations dramatically improve performance:
● Path Compression: This optimization is applied during the find(i) operation.
After the root r of the set containing i is found, the algorithm retraces the path
from i to r and makes every node on that path point directly to the root r. This
significantly flattens the tree structure, speeding up future find operations for
any node on that path.111 The typical recursive implementation achieves this
concisely: parent[i] = find(parent[i]).111
● Union by Rank / Union by Size: This optimization guides the union(i, j) operation
to keep the trees relatively balanced and shallow.
○ Union by Rank: Each root node maintains a rank, which is an upper bound on
the height of the tree rooted at that node. When uniting two trees with roots
root_i and root_j, the root with the smaller rank is attached as a child to the
root with the larger rank. If the ranks are equal, one is chosen arbitrarily as
the parent, and its rank is incremented by one.112 Path compression can
change the actual height, so rank becomes an upper bound rather than the
exact height.126
○ Union by Size: Each root node maintains the size (number of nodes) of the
tree rooted at that node. When uniting two trees, the root of the smaller tree
(in terms of size) is attached as a child to the root of the larger tree. The size
of the new root is updated by adding the size of the smaller tree.111
Both heuristics, when combined with path compression, yield the same excellent
amortized time complexity.126 Union by size might be preferred if the size of the sets is
needed for other parts of an algorithm.133These two optimizations are highly
complementary. Union by Rank/Size ensures that the underlying tree structure
remains relatively balanced during unions, preventing the worst-case linear height
scenarios. Path Compression then drastically flattens the paths accessed during find
operations, making subsequent accesses along those paths nearly constant time.
While Union by Rank/Size alone guarantees O(log N) per operation, and Path
Compression alone provides an amortized O(log N) bound, it is their combination that
achieves the remarkable near-constant O(α(N)) amortized time complexity.123
class DisjointSetUnion {
private:
std::vector<int> parent;
std::vector<int> rank; // Utilizing Union by Rank
public:
// Constructor: Initializes the Disjoint Set Union structure with
n elements, each representing an independent set.
DisjointSetUnion(int n) {
parent.resize(n);
std::iota(parent.begin(), parent.end(), 0); // Initialize each
element as its own parent.
rank.resize(n, 0); // Initialize the rank of each set to 0.
}
// Example Usage:
// DisjointSetUnion dsu(10); // Instantiate a Disjoint Set Union for
10 elements (0-9).
// dsu.unite(1, 2);
// dsu.unite(2, 3);
// bool connectivityStatus = dsu.areConnected(1, 3); // Returns true,
indicating 1 and 3 are in the same set.
111
(Note: An alternative implementation using union by size would replace the rank
vector with a size vector initialized to 1, and the unite logic would compare sizes
instead of ranks, updating the size of the new root accordingly.)
4.5 Applications
The DSU data structure is incredibly useful in algorithms and problems involving
partitioning, connectivity, and equivalence relations:
● Finding Connected Components: Efficiently determines connected
components in undirected graphs, both statically and dynamically (as edges are
added).68
● Cycle Detection in Undirected Graphs: Detects cycles by checking if the
endpoints of an edge already belong to the same set before performing a union.27
● Kruskal's Algorithm for MST: Used to efficiently check if adding the next
cheapest edge would form a cycle by determining if the edge's endpoints are
already in the same component.45
● Network Connectivity: Determining if nodes in a network (computer, social) are
connected.56
● Image Processing: Grouping connected pixels (connected component
labeling).56
● Least Common Ancestor (LCA): Can be used as part of an efficient offline LCA
algorithm.114
● Equivalence Relations: Managing equivalence classes where elements can be
grouped based on transitive relationships.120
Problem List
The following table lists the problems, categorized by the primary algorithm(s)
typically used for their solution. Note that some problems can be solved using
multiple approaches.
Table 3: Practice Problems List
BFS Focused
DFS Focused
Number of 200 DFS / BFS / UF Medium Grid
Islands components 153
Dijkstra
Focused
Union-Find
Focused
Mixed / Other
This list provides a diverse set of problems covering the algorithms discussed.
Working through these problems will significantly enhance understanding and
proficiency in applying BFS, DFS, Dijkstra's algorithm, and Union-Find to various
graph-related challenges.
This completes the second part of the advanced graph algorithms study guide,
covering Topological Sort, Cycle Detection, Connectivity, Strongly Connected
Components, and the Union-Find data structure. The next parts will delve into
Minimum Spanning Trees and other advanced graph topics.
Works cited
1. Topological Sorting - Algorithms for Competitive Programming, accessed April
14, 2025, https://cp-algorithms.com/graph/topological-sort.html
2. Topological Sort - USACO Guide, accessed April 14, 2025,
https://usaco.guide/gold/toposort
3. Topologically Sorting a Directed Acyclic Graph - Bowdoin College, accessed April
14, 2025,
https://tildesites.bowdoin.edu/~ltoma/teaching/cs231/2021spring/Lectures/L11-
topsort.pdf
4. www.baeldung.com, accessed April 14, 2025, https://www.baeldung.com/cs/dag-
topological-sort#:~:text=In%20many%20applications%2C%20we%20use,a
%20DAG%20to%20represent%20tasks.
5. Understanding the Concept and 2 Applications - Topological Sort, accessed April
14, 2025, https://topological-sort.hashnode.dev/topological-sort-understanding-
the-concept-and-2-applications
6. Topological Sort Using DFS - Tutorial - takeUforward, accessed April 14, 2025,
https://takeuforward.org/data-structure/topological-sort-using-dfs/
7. Topological Sort Algorithm | Interview Cake, accessed April 14, 2025,
https://www.interviewcake.com/concept/java/topological-sort
8. Topological Sort Using DFS, accessed April 14, 2025,
https://blog.heycoach.in/topological-sort-using-dfs/
9. Cycle Detection and Topological Sort Algorithm | Labuladong Algo Notes,
accessed April 14, 2025,
https://labuladong.online/algo/en/data-structure/topological-sort/
10. Introduction to Topological Sort - LeetCode Discuss, accessed April 14, 2025,
https://leetcode.com/discuss/general-discussion/1078072/introduct
11. Topological Sort of Directed Acyclic Graph | Baeldung on Computer ..., accessed
April 14, 2025, https://www.baeldung.com/cs/dag-topological-sort
12. Kahn's Algorithm | Topological Sort Algorithm | BFS: G-22 - Tutorial, accessed
April 14, 2025, https://takeuforward.org/data-structure/kahns-algorithm-
topological-sort-algorithm-bfs-g-22/
13. Kahn's Algorithm for Topological Sorting - Interview kickstart, accessed April 14,
2025, https://interviewkickstart.com/blogs/learn/kahns-algorithm-topological-
sorting
14. Topological Sorting using Kahn's Algorithm - c++ - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/70649825/topological-
sorting-using-kahns-algorithm
15. Detect a Cycle in Directed Graph | Topological Sort | Kahn's Algorithm | G-23 -
takeUforward, accessed April 14, 2025, https://takeuforward.org/data-
structure/detect-a-cycle-in-directed-graph-topological-sort-kahns-algorithm-
g-23/
16. GeeksforGeeks-POTD/April 2025 GFG SOLUTION/06(Apr ... - GitHub, accessed
April 14, 2025,
https://github.com/Hunterdii/GeeksforGeeks-POTD/blob/main/April
%202025%20GFG%20SOLUTION/06(Apr)%20Topological%20sort.md
17. Distilled • LeetCode • Topological Sort - aman.ai, accessed April 14, 2025,
https://aman.ai/code/top-sort/
18. Topological Sorting in Graph Using DFS and BFS GeeksForGeeks - DEV
Community, accessed April 14, 2025, https://dev.to/prashantrmishra/topological-
sorting-in-graph-using-dfs-and-bfs-geeksforgeeks-28f2
19. Apply DFS for Topological Sorting of Directed Acyclic Graph in C++ -
Tutorialspoint, accessed April 14, 2025,
https://www.tutorialspoint.com/cplusplus-program-to-apply-dfs-to-perform-
the-topological-sorting-of-a-directed-acyclic-graph
20. Chapter 11 Depth-First Search, accessed April 14, 2025,
https://www.cs.cmu.edu/afs/cs/academic/class/15210-f14/www/lectures/graph-
dfs.pdf
21. 16.4.2 DFS and cycle detection: Topological sorting using DFS, accessed April 14,
2025,
https://courses.grainger.illinois.edu/cs374/fa2020/lec_prerec/16/16_4_2_0.pdf
22. Depth First Search - Algorithms for Competitive Programming, accessed April 14,
2025, https://cp-algorithms.com/graph/depth-first-search.html
23. Why use DFS to find cycles in an undirected graph and topological sorting to find
cycles in a directed graph? - Stack Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/16779699/why-use-dfs-to-find-cycles-in-
an-undirected-graph-and-topological-sorting-to-fin
24. Topological Sorting | GeeksforGeeks - YouTube, accessed April 14, 2025,
https://m.youtube.com/watch?v=Q9PIxaNGnig
25. Graph For Beginners [Problems | Pattern | Sample Solutions] - LeetCode Discuss,
accessed April 14, 2025,
https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-
Problems-or-Pattern-or-Sample-Solutions
26. Topological Sort (w/ DFS) + Course Schedule LeetCode - Reddit, accessed April
14, 2025,
https://www.reddit.com/r/leetcode/comments/dupmul/topological_sort_w_dfs_c
ourse_schedule_leetcode/
27. Checking a graph for acyclicity and finding a cycle in O(M) - Algorithms for
Competitive Programming, accessed April 14, 2025,
https://cp-algorithms.com/graph/finding-cycle.html
28. Cycle detection in Graph: C Program implementation - w3resource, accessed
April 14, 2025, https://www.w3resource.com/c-programming-exercises/graph/c-
graph-exercises-6.php
29. Algorithms for Detecting Cycles in Graphs: A Comprehensive Guide -
AlgoCademy, accessed April 14, 2025, https://algocademy.com/blog/algorithms-
for-detecting-cycles-in-graphs-a-comprehensive-guide/
30. Cycle Detection Using Union-Find, accessed April 14, 2025,
https://blog.heycoach.in/cycle-detection-using-union-find/
31. DETECTING CYCLE IN A GRAPH - Expert Mentoring, Customized ..., accessed
April 14, 2025, https://venkys.io/articles/details/detecting-cycle-in-a-graph
32. Graph theory - Wikipedia, accessed April 14, 2025,
https://en.wikipedia.org/wiki/Graph_theory
33. c++ - Detecting a cycle in a directed graph using DFS? - Stack ..., accessed April
14, 2025, https://stackoverflow.com/questions/31542031/detecting-a-cycle-in-a-
directed-graph-using-dfs
34. Can a 3 Color DFS be used to identify cycles (not just detect them)?, accessed
April 14, 2025, https://cs.stackexchange.com/questions/86148/can-a-3-color-
dfs-be-used-to-identify-cycles-not-just-detect-them
35. How to detect cycles in a directed graph using the iterative version of DFS? -
Stack Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/46506077/how-to-detect-cycles-in-a-
directed-graph-using-the-iterative-version-of-dfs
36. L06 : Cycle detection in graph using DFS | Graph Theory Part 1 | CodeNCode -
YouTube, accessed April 14, 2025, https://www.youtube.com/watch?
v=SKUOVLqcR9s
37. Detect Cycle in a Directed graph in C++ - YouTube, accessed April 14, 2025,
https://www.youtube.com/watch?v=CFKfmtTwpkw
38. How do you detect if there is a cycle in a graph? : r/C_Programming - Reddit,
accessed April 14, 2025,
https://www.reddit.com/r/C_Programming/comments/1581yts/how_do_you_dete
ct_if_there_is_a_cycle_in_a_graph/
39. G-19. Detect cycle in a directed graph using DFS | Java | C++ - YouTube,
accessed April 14, 2025, https://www.youtube.com/watch?v=9twcmtQj4DU
40. Cycle Detection in an Undirected Graph - TheJat.in, accessed April 14, 2025,
https://thejat.in/code/cycle-detection-in-an-undirected-graph
41. Cycle in an undirected graph using dfs - c++ - Stack Overflow, accessed April 14,
2025, https://stackoverflow.com/questions/49223190/cycle-in-an-undirected-
graph-using-dfs
42. detecting cycles directed graphs vs undirected : r/learnprogramming - Reddit,
accessed April 14, 2025,
https://www.reddit.com/r/learnprogramming/comments/108ldp7/detecting_cycl
es_directed_graphs_vs_undirected/
43. Detect Cycle in an Undirected Graph (using DFS) - Tutorial - takeUforward,
accessed April 14, 2025, https://takeuforward.org/data-structure/detect-cycle-
in-an-undirected-graph-using-dfs/
44. Union-Find Algorithm | Set 1 (Detect Cycle in an Undirected Graph) |
GeeksforGeeks, accessed April 14, 2025, https://www.youtube.com/watch?
v=mHz-mx-8lJ8
45. algorithm - Finding cycles: DFS versus union-find? - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/45272145/finding-cycles-
dfs-versus-union-find
46. Finding a cycle and saving its vertices in an undirected, unweighted graph using
BFS, accessed April 14, 2025,
https://stackoverflow.com/questions/69680969/finding-a-cycle-and-saving-its-
vertices-in-an-undirected-unweighted-graph-using
47. 15 Cycle detection In Undirected graph Using BFS - YouTube, accessed April 14,
2025, https://www.youtube.com/watch?v=1ZWTKJpIvpE
48. Detect Cycle in an Undirected Graph (using BFS) - Tutorial, accessed April 14,
2025, https://takeuforward.org/data-structure/detect-cycle-in-an-undirected-
graph-using-bfs/
49. Cycle Detection in Undirected Graph using BFS - YouTube, accessed April 14,
2025, https://www.youtube.com/watch?v=A8ko93TyOns
50. G-11. Detect a Cycle in an Undirected Graph using BFS | C++ | Java - YouTube,
accessed April 14, 2025, https://www.youtube.com/watch?v=BPlrALf1LDU
51. algorithm - Why DFS and not BFS for finding cycle in graphs - Stack ..., accessed
April 14, 2025, https://stackoverflow.com/questions/2869647/why-dfs-and-not-
bfs-for-finding-cycle-in-graphs
52. Disjoint Sets and Cycle Detection : r/computerscience - Reddit, accessed April
14, 2025,
https://www.reddit.com/r/computerscience/comments/p55w4v/disjoint_sets_an
d_cycle_detection/
53. Using Union find to check whether there is a cycle in a graph, accessed April 14,
2025, https://cs.stackexchange.com/questions/105828/using-union-find-to-
check-whether-there-is-a-cycle-in-a-graph
54. Can someone explain intuitively why union find works to find a cycle in an
undirected graph?, accessed April 14, 2025,
https://cs.stackexchange.com/questions/142492/can-someone-explain-
intuitively-why-union-find-works-to-find-a-cycle-in-an-undir
55. Detection of cycle in Graph using find and Union - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/43076950/detection-of-
cycle-in-graph-using-find-and-union
56. Union-Find For Cycle Detection, accessed April 14, 2025,
https://blog.heycoach.in/union-find-for-cycle-detection/
57. Kruskal's Algorithm Visually Explained | Disjoint Sets | Union By Rank | Path
Compression, accessed April 14, 2025, https://www.youtube.com/watch?
v=8HeLu8wuLqo
58. Union Find Kruskal's Algorithm - YouTube, accessed April 14, 2025,
https://www.youtube.com/watch?v=JZBQLXgSGfs&pp=0gcJCfcAhR29_xXO
59. Detect cycle in a graph using Kruskal's algorithm - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/29998332/detect-cycle-in-a-
graph-using-kruskals-algorithm
60. Does using union-find in Kruskal's algorithm actually affect worst-case runtime?,
accessed April 14, 2025, https://stackoverflow.com/questions/32040718/does-
using-union-find-in-kruskals-algorithm-actually-affect-worst-case-runtime
61. How to detect a cycle in an Undirected Graph using Disjoint Sets? - Stack
Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/43438419/how-to-detect-a-cycle-in-an-
undirected-graph-using-disjoint-sets
62. Disjoint Set | Union Find | Cycle Detection| Union By Rank | Path Compression -
YouTube, accessed April 14, 2025, https://m.youtube.com/watch?
v=0JE7hxr8c5c&t=0s
63. Union By Rank and Path Compression in Union-Find Algorithm ..., accessed April
14, 2025, https://www.geeksforgeeks.org/union-find-algorithm-set-2-union-by-
rank/
64. Kruskal's Algorithm: Key to Minimum Spanning Tree [MST] - Simplilearn.com,
accessed April 14, 2025, https://www.simplilearn.com/tutorials/data-structure-
tutorial/kruskal-algorithm
65. Longest Cycle in a Graph - LeetCode, accessed April 14, 2025,
https://leetcode.com/problems/longest-cycle-in-a-graph/
66. LeetCode Problems by Official Solution Category - Software Engineering
Handbook, accessed April 14, 2025, https://dwf.dev/docs/learning-resources/lc-
solution-categories
67. BFS and DFS applications - Tyler Moore, accessed April 14, 2025,
https://tylermoore.ens.utulsa.edu/courses/cse3353/slides/l07-handout.pdf
68. Check Vertices in Undirected Graph - Tutorialspoint, accessed April 14, 2025,
https://www.tutorialspoint.com/queries-to-check-if-vertices-x-and-y-are-in-
the-same-connected-component-of-an-undirected-graph
69. Finding Connected Components - Algorithms for Competitive ..., accessed April
14, 2025, https://cp-algorithms.com/graph/search-for-connected-
components.html
70. DFS to find the number of connected components and displaying a cycle -
Reddit, accessed April 14, 2025,
https://www.reddit.com/r/cpp_questions/comments/k95aht/dfs_to_find_the_nu
mber_of_connected_components/
71. Connected Components in an undirected graph - c++ - Stack Overflow,
accessed April 14, 2025,
https://stackoverflow.com/questions/24119528/connected-components-in-an-
undirected-graph
72. 323. Number of Connected Components in an Undirected Graph - In-Depth
Explanation, accessed April 14, 2025, https://algo.monster/liteproblems/323
73. C++ implementation of the algorithm to find number of connected components
in a graph. · Issue #6555 · OpenGenus/cosmos - GitHub, accessed April 14, 2025,
https://github.com/OpenGenus/cosmos/issues/6555
74. Connected Components in a Graph | Baeldung on Computer Science, accessed
April 14, 2025, https://www.baeldung.com/cs/graph-connected-components
75. Number of Connected Components in an Undirected Graph ..., accessed April 14,
2025, https://gkgaurav31.github.io/posts/number-of-connected-components-in-
an-undirected-graph/
76. Strongly Connected Components - USACO Guide, accessed April 14, 2025,
https://usaco.guide/adv/SCC
77. Strongly Connected Components - Neo4j Graph Data Science, accessed April
14, 2025,
https://neo4j.com/docs/graph-data-science/current/algorithms/strongly-
connected-components/
78. CS 161 (Stanford, Winter 2023) Lecture 10 Strongly Connected Components,
accessed April 14, 2025,
https://stanford-cs161.github.io/winter2023/assets/files/lecture10-notes.pdf
79. Strongly Connected Components - Programiz, accessed April 14, 2025,
https://www.programiz.com/dsa/strongly-connected-components
80. Tarjan's Algorithm for Strongly Connected Components - Topcoder, accessed
April 14, 2025, https://www.topcoder.com/thrive/articles/tarjans-algorithm-for-
strongly-connected-components
81. Algorithm for Finding SCC (Strongly Connected Components) in Graphs -
Hypermode, accessed April 14, 2025, https://hypermode.com/blog/algorithm-
for-finding-scc
82. Strongly connected component - Wikipedia, accessed April 14, 2025,
https://en.wikipedia.org/wiki/Strongly_connected_component
83. Kosaraju's Algorithm - Tpoint Tech, accessed April 14, 2025,
https://www.tpointtech.com/kosarajus-algorithm
84. Strongly Connected Components (SCC's), accessed April 14, 2025,
https://tildesites.bowdoin.edu/~ltoma/teaching/cs231/fall14/Lectures/12-SCC/
scc.pdf
85. All Graph Algorithms - One Stop Destination [Standard Implementations] -
LeetCode, accessed April 14, 2025,
https://leetcode.com/discuss/study-guide/6132428/All-Graph-Algorithms-One-
Stop-Destination-Standard-Implementations
86. graph theory - Uses of Strongly Connected Components? - Mathematics Stack
Exchange, accessed April 14, 2025,
https://math.stackexchange.com/questions/32041/uses-of-strongly-connected-
components
87. Difference between a directed cycle and a strongly connected component -
Stack Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/74413037/difference-between-a-directed-
cycle-and-a-strongly-connected-component
88. c++ - Strongly Connected Components (Kosaraju's Algo) - Stack Overflow,
accessed April 14, 2025, https://stackoverflow.com/questions/78841105/strongly-
connected-components-kosarajus-algo?r=31
89. Kosaraju's algorithm - Wikipedia, accessed April 14, 2025,
https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
90. Depth First Search Tutorials & Notes | Algorithms - HackerEarth, accessed April
14, 2025, https://www.hackerearth.com/practice/algorithms/graphs/depth-first-
search/tutorial/
91. Union-Find or DFS: which one is better to find connected component? - Stack
Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/28398101/union-find-or-dfs-which-one-is-
better-to-find-connected-component
92. Strongly Connected Components - Kosaraju's Algorithm: G-54 - Tutorial -
takeUforward, accessed April 14, 2025, https://takeuforward.org/graph/strongly-
connected-components-kosarajus-algorithm-g-54/
93. Algorithms/Graph Algorithms/Kosaraju's Algorithm.cpp at master ·
PetarV-/Algorithms - GitHub, accessed April 14, 2025,
https://github.com/PetarV-/Algorithms/blob/master/Graph%20Algorithms/
Kosaraju's%20Algorithm.cpp
94. Algorithms/Graph algorithms/SCC Kosaraju's algorithm.cpp at master · SH-
anonta/Algorithms - GitHub, accessed April 14, 2025, https://github.com/SH-
anonta/Algorithms/blob/master/Graph%20algorithms/SCC%20Kosaraju's
%20algorithm.cpp
95. Kosaraju's Algorithm Implementation Problem - c++ - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/61211219/kosarajus-
algorithm-implementation-problem
96. Strongly Connected Components | GeeksforGeeks, accessed April 14, 2025,
https://www.geeksforgeeks.org/strongly-connected-components/
97. Kosaraju's algorithm's time complexity - Computer Science Stack Exchange,
accessed April 14, 2025,
https://cs.stackexchange.com/questions/39955/kosarajus-algorithms-time-
complexity
98. C++ implementation of tarjan's algorithm for finding Strongly connected
components, accessed April 14, 2025,
https://gist.github.com/APwhitehat/e2ae94b811defc7407bc320f98fd268b
99. Tarjan Algorithms for SCC - graph theory - Stack Overflow, accessed April 14,
2025, https://stackoverflow.com/questions/78654688/tarjan-algorithms-for-scc
100. Tarjan's Algorithm Guide: Upsolving Competitive Programming Challenges,
accessed April 14, 2025, https://blog.garybricks.com/tarjan-algorithm-beginner-
overview
101. Tarjan - Rosetta Code, accessed April 14, 2025,
https://rosettacode.org/wiki/Tarjan
102. Finding Strongly Connected Components: Tarjan's Algorithm | Baeldung on
Computer Science, accessed April 14, 2025, https://www.baeldung.com/cs/scc-
tarjans-algorithm
103. Tarjan's Algorithm: Time Complexity and slight modification possibility - Stack
Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/24114178/tarjans-algorithm-time-
complexity-and-slight-modification-possibility
104. Tarjan's Strongly Connected Component (SCC) Algorithm (UPDATED) | Graph
Theory, accessed April 14, 2025, https://www.youtube.com/watch?
v=wUgWX0nc4NY&pp=0gcJCfcAhR29_xXO
105. Number of Provinces - LeetCode, accessed April 14, 2025,
https://leetcode.com/problems/number-of-provinces/
106. Number of Connected Components in an Undirected Graph - LeetCode,
accessed April 14, 2025, https://leetcode.com/problems/number-of-connected-
components-in-an-undirected-graph/
107. 1192. Critical Connections in a Network - In-Depth Explanation, accessed April
14, 2025, https://algo.monster/liteproblems/1192
108. List of graph algorithms for coding interview - LeetCode Discuss, accessed April
14, 2025, https://leetcode.com/discuss/general-discussion/753236/list-of-graph-
algorithms-for-coding-interview
109. Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree - LeetCode,
accessed April 14, 2025, https://leetcode.com/problems/find-critical-and-
pseudo-critical-edges-in-minimum-spanning-tree/
110. Min Cost to Connect All Points - LeetCode, accessed April 14, 2025,
https://leetcode.com/problems/min-cost-to-connect-all-points/discuss/
843940/C%2B%2B-MST%3A-Kruskal-%2B-Prim's-%2B-Complete-Graph
111. Disjoint Set Union - USACO Guide, accessed April 14, 2025,
https://usaco.guide/gold/dsu
112. ICS 311 #16: Disjoint Sets and Union-Find - University of Hawaii System,
accessed April 14, 2025,
https://www2.hawaii.edu/~nodari/teaching/s18/Notes/Topic-16.html
113. Disjoint Set Union (Union Find) - HackerEarth, accessed April 14, 2025,
https://www.hackerearth.com/practice/notes/disjoint-set-union-union-find/
114. Disjoint Set Union - Algorithms for Competitive Programming, accessed April 14,
2025, https://cp-algorithms.com/data_structures/disjoint_set_union.html
115. Union-Find (Disjoint Set): A Comprehensive Guide for Efficient Data Structure
Operations, accessed April 14, 2025, https://algocademy.com/blog/union-find-
disjoint-set-a-comprehensive-guide-for-efficient-data-structure-operations/
116. A crash course on Disjoint Set Union (aka Union Find) data structure. - Design
Gurus, accessed April 14, 2025,
https://www.designgurus.io/answers/detail/disjoint-set-union-aka-union-find
117. Union-Find With Union By Rank/Size - Explore Insights, Tips And Articles With
HeyCoach Blogs, accessed April 14, 2025, https://blog.heycoach.in/union-find-
with-union-by-rank-size/
118. Disjoint Set | Union by Rank | Union by Size | Path Compression: G ..., accessed
April 14, 2025, https://takeuforward.org/data-structure/disjoint-set-union-by-
rank-union-by-size-path-compression-g-46/
119. Union-Find Program Debugging : r/Cplusplus - Reddit, accessed April 14, 2025,
https://www.reddit.com/r/Cplusplus/comments/16ld3ex/unionfind_program_deb
ugging/
120. 13.2 Disjoint set data structure and union-find algorithms - Fiveable, accessed
April 14, 2025, https://library.fiveable.me/introduction-algorithms/unit-13/disjoint-
set-data-structure-union-find-algorithms/study-guide/l19GnnC5CX6zvbBo
121. Implementing Disjoint Sets (Union Find) in C++ - Stack Overflow, accessed April
14, 2025, https://stackoverflow.com/questions/4498833/implementing-disjoint-
sets-union-find-in-c
122. Union find, accessed April 14, 2025,
https://courses.cs.washington.edu/courses/cse332/16sp/lectures/Lecture25/25_h
o.pdf
123. Union-Find - cs.Princeton, accessed April 14, 2025,
https://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/UnionFind.pdf
124. Complexity/implementation of disjoint-set (union-find) in `DataStructures.jl` -
Julia Discourse, accessed April 14, 2025,
https://discourse.julialang.org/t/complexity-implementation-of-disjoint-set-
union-find-in-datastructures-jl/119050
125. Union by Rank and Path Compression in Union-Find Algorithm - Tutorialspoint,
accessed April 14, 2025, https://www.tutorialspoint.com/union-by-rank-and-
path-compression-in-union-find-algorithm
126. How do path compression and union by rank complement each other? - Stack
Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/41686826/how-do-path-compression-and-
union-by-rank-complement-each-other
127. Is this Union Find really O(n) as they claim? - Stack Overflow, accessed April 14,
2025, https://stackoverflow.com/questions/71453109/is-this-union-find-really-
on-as-they-claim
128. Union-Find path compression efficiency - algorithm - Stack Overflow, accessed
April 14, 2025, https://stackoverflow.com/questions/47257244/union-find-path-
compression-efficiency
129. Union find - is rank necessary? : r/leetcode - Reddit, accessed April 14, 2025,
https://www.reddit.com/r/leetcode/comments/1e5ayix/union_find_is_rank_neces
sary/
130. Complexity of union-find with path-compression, without rank, accessed April
14, 2025, https://cs.stackexchange.com/questions/48649/complexity-of-union-
find-with-path-compression-without-rank
131. Disjoint set union implementation using c++ - Stack Overflow, accessed April 14,
2025, https://stackoverflow.com/questions/60955485/disjoint-set-union-
implementation-using-c
132. Union Find. Why we don't change rank in find call? - LeetCode Discuss,
accessed April 14, 2025,
https://leetcode.com/discuss/explore/graph/4155748/Union-Find.-Why-we-
don't-change-rank-in-find-call/
133. union by size vs union by rank in disjoint-set algorithm - Stack Overflow,
accessed April 14, 2025, https://stackoverflow.com/questions/65009794/union-
by-size-vs-union-by-rank-in-disjoint-set-algorithm
134. Runtime difference bewteen Union by Rank and Union by Size for union-find,
accessed April 14, 2025,
https://cs.stackexchange.com/questions/128204/runtime-difference-bewteen-
union-by-rank-and-union-by-size-for-union-find
135. Why is the time complexity of performing n union find (union by size) operations
O(n log n)?, accessed April 14, 2025,
https://stackoverflow.com/questions/53149097/why-is-the-time-complexity-of-
performing-n-union-find-union-by-size-operations
136. Amortized analysis and Union-Find, accessed April 14, 2025,
https://www.cs.upc.edu/~mjserna/docencia/grauA/T19/Union-Find.pdf
137. Union-Find and Amortization 1 Introduction - MIT OpenCourseWare, accessed
April 14, 2025, https://ocw.mit.edu/courses/6-046j-design-and-analysis-of-
algorithms-spring-2015/
d25d9d3ba96321326601c8f6dd073e60_MIT6_046JS15_Recitation3.pdf
138. Lecture 1: Amortized Analysis & Union Find - Cheriton School of Computer
Science - University of Waterloo, accessed April 14, 2025,
https://cs.uwaterloo.ca/~r5olivei/courses/2020-fall-cs466/lecture1.pdf
139. Union-Find - Carnegie Mellon University, accessed April 14, 2025,
https://www.cs.cmu.edu/~15451-f23/lectures/lecture06-unionfind.pdf
140. Graph algorithms + problems to practice - LeetCode Discuss, accessed April 14,
2025, https://leetcode.com/discuss/study-guide/1326900/
141. Implement Kruskal's Algorithm in C++ - DEV Community, accessed April 14,
2025, https://dev.to/nokha_debbarma/implement-kruskal-s-algorithm-in-c-29cn
142. Union-Find In Kruskal's Algorithm (MST), accessed April 14, 2025,
https://blog.heycoach.in/union-find-in-kruskals-algorithm-mst/
143. 14.7. Kruskal's Algorithm — CS3 Data Structures & Algorithms - OpenDSA,
accessed April 14, 2025,
https://opendsa-server.cs.vt.edu/ODSA/Books/CS3/html/Kruskal.html
144. Kruskal's Algorithm and Union-Find, accessed April 14, 2025,
https://web.cs.unlv.edu/larmore/Courses/CSC477/S25/Handouts/unionfnd.pdf
145. How to use union-find, minheap, Kruskal's, and a sort algorithm to create a
minimum cost spanning tree? (C++) - Stack Overflow, accessed April 14, 2025,
https://stackoverflow.com/questions/4916287/how-to-use-union-find-minheap-
kruskals-and-a-sort-algorithm-to-create-a-mini
146. Kruskal's Algorithm - Programiz, accessed April 14, 2025,
https://www.programiz.com/dsa/kruskal-algorithm
147. 6.3 Applications of minimum spanning trees - Graph Theory - Fiveable,
accessed April 14, 2025,
https://library.fiveable.me/graph-theory/unit-6/applications-minimum-spanning-
trees/study-guide/iOCen7zmSVC9rHOF
148. Algorithms in Systems Engineering ISE 172 Lecture 22, accessed April 14, 2025,
https://coral.ise.lehigh.edu/~ted/files/ie172/lectures/Lecture22.pdf
149. Union Find Kruskal's Algorithm - YouTube, accessed April 14, 2025,
https://www.youtube.com/watch?v=JZBQLXgSGfs&pp=0gcJCdgAo7VqN5tD
150. Kruskal's Algorithm + Union-Find & MST LeetCode 1584. Min Cost to Connect All
Points, accessed April 14, 2025, https://www.youtube.com/watch?
v=JgmClRWPMX4
151. G-47. Kruskal's Algorithm - Minimum Spanning Tree - C++ and Java - YouTube,
accessed April 14, 2025, https://www.youtube.com/watch?v=DMnDM_sxVig
152. BFS and DFS Graph Problems: Easy to Medium Difficulty - LeetCode Discuss,
accessed April 14, 2025,
https://leetcode.com/discuss/interview-question/5039797/BFS-and-DFS-Graph-
Problems%3A-Easy-to-Medium-Difficulty/
153. Breadth-First Search (BFS) - Shortest Paths in Unweighted Graphs | Interview
Cake, accessed April 14, 2025,
https://www.interviewcake.com/concept/python/bfs?
154. Clone Graph: Ace LeetCode with DFS & BFS - Sean Coughlin's Blog, accessed
April 14, 2025, https://blog.seancoughlin.me/mastering-the-clone-graph-
problem-on-leetcode-a-comprehensive-guide
155. Number of Islands - LeetCode, accessed April 14, 2025,
https://leetcode.com/problems/number-of-islands/
156. Shortest Paths with Unweighted Edges - USACO Guide, accessed April 14, 2025,
https://usaco.guide/gold/unweighted-shortest-paths?lang=java
157. Solving LeetCode Problems Using Graph Theory - HackerNoon, accessed April
14, 2025, https://hackernoon.com/solving-leetcode-problems-using-graph-
theory
158. Graph Algorithms One Place | Dijkstra | Bellman Ford | Floyd Warshall | Prims |
Kruskals | DSU - LeetCode Discuss, accessed April 14, 2025,
https://leetcode.com/discuss/study-guide/969327/Graph-Algorithms-One-
Place-or-Dijkstra-or-Bellman-Ford-or-Floyd-Warshall-or-Prims-or-Kruskals-or-
DSU