Dsa Long Answer Questions
Dsa Long Answer Questions
Steps
1. Initialize a set for visited vertices and a priority queue for edges.
2. Start from any vertex and add all its connecting edges to the priority queue.
3. Select the smallest edge from the queue and check if adding it forms a cycle.
4. If no cycle, add the edge to the MST and mark the vertex as visited.
5. Repeat until all vertices are included in the MST.
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.graph = {i: [] for i in range(vertices)}
while min_heap:
weight, current, parent = heapq.heappop(min_heap)
if current not in visited:
visited.add(current)
if parent != -1:
mst.append((parent, current, weight))
total_weight += weight
for neighbor, wt in self.graph[current]:
if neighbor not in visited:
heapq.heappush(min_heap, (wt, neighbor, current))
Output
MST Edges: [(0, 1, 2), (1, 2, 3), (1, 4, 5), (0, 3, 6)]
Total Weight: 16
Diagram
Graph visualization with vertices (0-4) and weights on edges:
6
(0)---(3)
| \ \
2 8 7
| \ \
(1)----(2)----(4)
3 5
MST: {(0, 1), (1, 2), (1, 4), (0, 3)} with total weight = 16.
while queue:
vertex = queue.pop(0)
result.append(vertex)
Output
BFS Traversal: [0, 1, 2, 3, 4]
DFS Traversal: [0, 1, 3, 4, 2]
Diagram
Graph visualization with vertices (0-4):
(0)
/ \
(1) (2)
/ \
(3) (4)
BFS: 0 → 1 → 2 → 3 → 4
DFS: 0 → 1 → 3 → 4 → 2
3. Kruskal's Algorithm
Definition
Kruskal's algorithm is used to find the Minimum Spanning Tree (MST) of a graph. It works by
sorting all edges in non-decreasing order of their weights and adding them one by one to the
MST, provided they don’t form a cycle.
Steps
1. Sort all the edges of the graph in increasing order of weight.
2. Use a disjoint-set (union-find) data structure to ensure no cycles are formed when adding
edges.
3. Pick the smallest edge and check if it forms a cycle. If not, add it to the MST.
4. Repeat until there are (V-1) edges in the MST.
def kruskal(self):
self.edges.sort()
parent = {i: i for i in range(self.vertices)}
rank = {i: 0 for i in range(self.vertices)}
mst = []
for weight, u, v in self.edges:
root_u = self.find(parent, u)
root_v = self.find(parent, v)
if root_u != root_v:
mst.append((u, v, weight))
self.union(parent, rank, root_u, root_v)
return mst
mst = graph.kruskal()
print("Edges in MST:", mst)
Runtime Output
Edges in MST: [(2, 3, 4), (0, 3, 5), (0, 1, 10)]
Time Complexity
Sorting edges: O(ElogE)O(E \log E)O(ElogE)
Union-find operations: O(ElogV)O(E \log V)O(ElogV)
Overall: O(ElogE+ElogV)O(E \log E + E \log V)O(ElogE+ElogV).
4. Prim's Algorithm
Definition
Prim's algorithm is another method to find the MST. It starts with an arbitrary vertex and grows
the MST by adding the smallest edge connecting the current MST to a vertex not yet in the MST.
Steps
1. Start with any vertex as the initial MST.
2. Use a priority queue to fetch the smallest edge connecting the MST to any vertex outside
the MST.
3. Add the edge to the MST and include the new vertex.
4. Repeat until all vertices are included.
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.graph = {i: [] for i in range(vertices)}
while pq:
weight, u = heapq.heappop(pq)
if not visited[u]:
visited[u] = True
mst_weight += weight
for edge in self.graph[u]:
if not visited[edge[1]]:
heapq.heappush(pq, edge)
return mst_weight
mst_weight = graph.prim()
print("Total weight of MST:", mst_weight)
Runtime Output
Total weight of MST: 19
Time Complexity
Using priority queue: O((V+E)logV)O((V + E) \log V)O((V+E)logV).
5. Dijkstra's Algorithm
Definition
Dijkstra's algorithm finds the shortest path from a source vertex to all other vertices in a
weighted graph. It assumes all weights are non-negative.
Steps
1. Initialize distances from the source as infinity, except for the source itself, which is 0.
2. Use a priority queue to fetch the vertex with the smallest distance.
3. Update distances for its neighbors if a shorter path is found.
4. Repeat until all vertices are processed.
while pq:
curr_distance, u = heapq.heappop(pq)
if curr_distance > distances[u]:
continue
for v, weight in self.graph[u]:
distance = curr_distance + weight
if distance < distances[v]:
distances[v] = distance
heapq.heappush(pq, (distance, v))
return distances
distances = graph.dijkstra(0)
print("Shortest distances from vertex 0:", distances)
Runtime Output
Shortest distances from vertex 0: {0: 0, 1: 7, 2: 9, 3: 19, 4: 3}
Time Complexity
Using priority queue: O((V+E)logV)O((V + E) \log V)O((V+E)logV).