|
| 1 | +--- |
| 2 | +id: versatile-graph-toolkit |
| 3 | +title: Versatile Graph Toolkit |
| 4 | +sidebar_label: 0005 - Versatile Graph Toolkit |
| 5 | +tags: [Graph Algorithms, Dijkstra, Kruskal, DFS, BFS, C++, Problem Solving] |
| 6 | +description: This is a solution for developing a versatile graph theory toolkit designed to address a wide range of DSA problems. |
| 7 | +--- |
| 8 | + |
| 9 | +## Problem Statement |
| 10 | + |
| 11 | +### Problem Description |
| 12 | + |
| 13 | +The versatile graph theory toolkit provides implementations for fundamental graph algorithms such as Depth-First Search (DFS), Breadth-First Search (BFS), Dijkstra’s algorithm, and Kruskal’s algorithm. This toolkit offers an easy-to-use interface, enabling users to efficiently solve various DSA problems involving graph theory. |
| 14 | + |
| 15 | +### Examples |
| 16 | + |
| 17 | +**Example 1:** |
| 18 | + |
| 19 | +```plaintext |
| 20 | +Input: |
| 21 | +Number of vertices: 5 |
| 22 | +Edges: |
| 23 | +0 1 4 |
| 24 | +0 2 2 |
| 25 | +1 2 1 |
| 26 | +1 3 5 |
| 27 | +2 3 8 |
| 28 | +2 4 10 |
| 29 | +3 4 2 |
| 30 | +Output: |
| 31 | +DFS Traversal: 0 1 2 3 4 |
| 32 | +BFS Traversal: 0 1 2 3 4 |
| 33 | +Shortest Path from 0 to 4 (Dijkstra): 10 |
| 34 | +Minimum Spanning Tree (Kruskal): |
| 35 | +Edge: 1-2 Weight: 1 |
| 36 | +Edge: 3-4 Weight: 2 |
| 37 | +Edge: 0-2 Weight: 2 |
| 38 | +Edge: 0-1 Weight: 4 |
| 39 | +
|
| 40 | +``` |
| 41 | + |
| 42 | +### Constraints |
| 43 | +- The toolkit should handle up to 10^5 vertices and edges. |
| 44 | +- The graph can be directed or undirected, weighted or unweighted. |
| 45 | + |
| 46 | +## Solution of Given Problem |
| 47 | + |
| 48 | +### Intuition and Approach |
| 49 | + |
| 50 | +The versatile graph theory toolkit is designed with the following algorithms: |
| 51 | + |
| 52 | +1. Depth-First Search (DFS): Traverses the graph in a depthward motion, utilizing a stack or recursion. |
| 53 | +2. Breadth-First Search (BFS): Traverses the graph level by level, utilizing a queue. |
| 54 | +3. Dijkstra’s Algorithm: Finds the shortest path from a single source to all other vertices in a graph with non-negative weights. |
| 55 | +4. Kruskal’s Algorithm: Finds the Minimum Spanning Tree (MST) for a graph by sorting edges and applying the union-find structure. |
| 56 | + |
| 57 | +### Approaches |
| 58 | + |
| 59 | +#### Codes in Different Languages |
| 60 | + |
| 61 | +<Tabs> |
| 62 | + <TabItem value="cpp" label="C++"> |
| 63 | + <SolutionAuthor name="sjain1909"/> |
| 64 | + ```cpp |
| 65 | + #include <bits/stdc++.h> |
| 66 | + using namespace std; |
| 67 | + |
| 68 | +void DFS(int v, vector<vector<int>>& adj, vector<bool>& visited) { |
| 69 | + stack<int> stack; |
| 70 | + stack.push(v); |
| 71 | + |
| 72 | + while (!stack.empty()) { |
| 73 | + int u = stack.top(); |
| 74 | + stack.pop(); |
| 75 | + |
| 76 | + if (!visited[u]) { |
| 77 | + cout << u << " "; |
| 78 | + visited[u] = true; |
| 79 | + } |
| 80 | + |
| 81 | + for (int i = adj[u].size() - 1; i >= 0; --i) { |
| 82 | + if (!visited[adj[u][i]]) { |
| 83 | + stack.push(adj[u][i]); |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | +} |
| 88 | + |
| 89 | +void BFS(int v, vector<vector<int>>& adj, vector<bool>& visited) { |
| 90 | + queue<int> queue; |
| 91 | + queue.push(v); |
| 92 | + visited[v] = true; |
| 93 | + |
| 94 | + while (!queue.empty()) { |
| 95 | + int u = queue.front(); |
| 96 | + queue.pop(); |
| 97 | + cout << u << " "; |
| 98 | + |
| 99 | + for (int i = 0; i < adj[u].size(); ++i) { |
| 100 | + if (!visited[adj[u][i]]) { |
| 101 | + queue.push(adj[u][i]); |
| 102 | + visited[adj[u][i]] = true; |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | +} |
| 107 | + |
| 108 | +void Dijkstra(int src, vector<vector<pair<int, int>>>& adj, int V) { |
| 109 | + vector<int> dist(V, INT_MAX); |
| 110 | + dist[src] = 0; |
| 111 | + priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; |
| 112 | + pq.push({0, src}); |
| 113 | + |
| 114 | + while (!pq.empty()) { |
| 115 | + int u = pq.top().second; |
| 116 | + pq.pop(); |
| 117 | + |
| 118 | + for (auto& edge : adj[u]) { |
| 119 | + int v = edge.first; |
| 120 | + int weight = edge.second; |
| 121 | + |
| 122 | + if (dist[u] + weight < dist[v]) { |
| 123 | + dist[v] = dist[u] + weight; |
| 124 | + pq.push({dist[v], v}); |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + for (int i = 0; i < V; ++i) { |
| 130 | + cout << "Distance from " << src << " to " << i << ": " << dist[i] << "\n"; |
| 131 | + } |
| 132 | +} |
| 133 | + |
| 134 | +struct Edge { |
| 135 | + int u, v, weight; |
| 136 | + bool operator<(const Edge& other) const { |
| 137 | + return weight < other.weight; |
| 138 | + } |
| 139 | +}; |
| 140 | + |
| 141 | +int find(vector<int>& parent, int i) { |
| 142 | + if (parent[i] == -1) |
| 143 | + return i; |
| 144 | + return parent[i] = find(parent, parent[i]); |
| 145 | +} |
| 146 | + |
| 147 | +void unionSets(vector<int>& parent, vector<int>& rank, int x, int y) { |
| 148 | + int xroot = find(parent, x); |
| 149 | + int yroot = find(parent, y); |
| 150 | + |
| 151 | + if (rank[xroot] < rank[yroot]) { |
| 152 | + parent[xroot] = yroot; |
| 153 | + } else if (rank[xroot] > rank[yroot]) { |
| 154 | + parent[yroot] = xroot; |
| 155 | + } else { |
| 156 | + parent[yroot] = xroot; |
| 157 | + rank[xroot]++; |
| 158 | + } |
| 159 | +} |
| 160 | + |
| 161 | +void Kruskal(vector<Edge>& edges, int V) { |
| 162 | + sort(edges.begin(), edges.end()); |
| 163 | + vector<int> parent(V, -1); |
| 164 | + vector<int> rank(V, 0); |
| 165 | + vector<Edge> result; |
| 166 | + |
| 167 | + for (auto& edge : edges) { |
| 168 | + int x = find(parent, edge.u); |
| 169 | + int y = find(parent, edge.v); |
| 170 | + |
| 171 | + if (x != y) { |
| 172 | + result.push_back(edge); |
| 173 | + unionSets(parent, rank, x, y); |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + cout << "Minimum Spanning Tree:\n"; |
| 178 | + for (auto& edge : result) { |
| 179 | + cout << "Edge: " << edge.u << "-" << edge.v << " Weight: " << edge.weight << "\n"; |
| 180 | + } |
| 181 | +} |
| 182 | + |
| 183 | +int main() { |
| 184 | + int V, E; |
| 185 | + cout << "Enter the number of vertices: "; |
| 186 | + cin >> V; |
| 187 | + cout << "Enter the number of edges: "; |
| 188 | + cin >> E; |
| 189 | + |
| 190 | + vector<vector<int>> adj(V); |
| 191 | + vector<vector<pair<int, int>>> adjWeighted(V); |
| 192 | + vector<Edge> edges; |
| 193 | + |
| 194 | + cout << "Enter the edges (u v weight): \n"; |
| 195 | + for (int i = 0; i < E; ++i) { |
| 196 | + int u, v, weight; |
| 197 | + cin >> u >> v >> weight; |
| 198 | + adj[u].push_back(v); |
| 199 | + adj[v].push_back(u); |
| 200 | + adjWeighted[u].push_back({v, weight}); |
| 201 | + adjWeighted[v].push_back({u, weight}); |
| 202 | + edges.push_back({u, v, weight}); |
| 203 | + } |
| 204 | + |
| 205 | + vector<bool> visited(V, false); |
| 206 | + cout << "DFS Traversal: "; |
| 207 | + DFS(0, adj, visited); |
| 208 | + cout << "\n"; |
| 209 | + |
| 210 | + fill(visited.begin(), visited.end(), false); |
| 211 | + cout << "BFS Traversal: "; |
| 212 | + BFS(0, adj, visited); |
| 213 | + cout << "\n"; |
| 214 | + |
| 215 | + cout << "Shortest Path from 0 using Dijkstra's algorithm:\n"; |
| 216 | + Dijkstra(0, adjWeighted, V); |
| 217 | + cout << "\n"; |
| 218 | + |
| 219 | + cout << "Minimum Spanning Tree using Kruskal's algorithm:\n"; |
| 220 | + Kruskal(edges, V); |
| 221 | + cout << "\n"; |
| 222 | + |
| 223 | + return 0; |
| 224 | +} |
| 225 | +``` |
| 226 | +
|
| 227 | + </TabItem> |
| 228 | +</Tabs> |
| 229 | +
|
| 230 | +### Complexity Analysis |
| 231 | +
|
| 232 | +1. Time Complexity: Varies depending on the algorithm: |
| 233 | +- DFS: $O(V + E)$ |
| 234 | +- BFS: $O(V + E)$ |
| 235 | +- Dijkstra’s Algorithm: $O((V + E) \log V)$ |
| 236 | +- Kruskal’s Algorithm: $O(E \log E)$ |
| 237 | +2. Space Complexity: $O(V + E)$ for adjacency lists and $O(V)$ for auxiliary structures. |
| 238 | +
|
| 239 | +The time complexity is determined by the relaxation of edges in the graph. The space complexity is linear due to the storage of distances. |
| 240 | +
|
| 241 | +## Video Explanation of Given Problem |
| 242 | +
|
| 243 | + <LiteYouTubeEmbed |
| 244 | + id="obWXjtg0L64" |
| 245 | + params="autoplay=1&autohide=1&showinfo=0&rel=0" |
| 246 | + title="Problem Explanation | Solution | Approach" |
| 247 | + poster="maxresdefault" |
| 248 | + webp |
| 249 | + /> |
| 250 | +--- |
| 251 | +
|
| 252 | +<h2>Authors:</h2> |
| 253 | +
|
| 254 | +<div style={{display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: '10px'}}> |
| 255 | +{['sjain1909'].map(username => ( |
| 256 | + <Author key={username} username={username} /> |
| 257 | +))} |
| 258 | +</div> |
0 commit comments