0% found this document useful (0 votes)
8 views15 pages

23350 Assignment Graphs 02

The document contains multiple programming assignments related to graph algorithms, including implementations of Kruskal's and Prim's algorithms for finding minimum spanning trees, Dijkstra's algorithm for shortest paths, and the Floyd-Warshall algorithm for all pairs shortest paths. It also includes a topological sorting algorithm for directed acyclic graphs. Each section provides code examples in C++ along with explanations of the algorithms.

Uploaded by

shivann2006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views15 pages

23350 Assignment Graphs 02

The document contains multiple programming assignments related to graph algorithms, including implementations of Kruskal's and Prim's algorithms for finding minimum spanning trees, Dijkstra's algorithm for shortest paths, and the Floyd-Warshall algorithm for all pairs shortest paths. It also includes a topological sorting algorithm for directed acyclic graphs. Each section provides code examples in C++ along with explanations of the algorithms.

Uploaded by

shivann2006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

23350

DSA (ITC303)
AY: 2024-25

SUBMITTED BY
ROHIT KUMAR(23350)
III SEMESTER

BACHELOR OF TECHNOLOGY
in
INFORMATION TECHNOLOGY
23350

ASSIGNMENT- 10 (Graphs2)

Coding:-

1. WAP to implement Kruksal’s algorithm:-

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Structure to represent an edge


struct Edge {
int src, dest, weight;
};

// Structure to represent a graph


struct Graph {
int V, E; // V = Number of vertices, E = Number of edges
vector<Edge> edges;
};

// Function to find the parent of a node (with path compression)


int find(vector<int>& parent, int i) {
if (parent[i] != i) {
parent[i] = find(parent, parent[i]);
}
return parent[i];
}

// Function to perform union of two subsets (by rank)


void unionSets(vector<int>& parent, vector<int>& rank, int x, int y) {
int xroot = find(parent, x);
int yroot = find(parent, y);

if (rank[xroot] < rank[yroot]) {


parent[xroot] = yroot;
} else if (rank[xroot] > rank[yroot]) {
parent[yroot] = xroot;
} else {
parent[yroot] = xroot;
rank[xroot]++;
}
}

// Comparator function to sort edges by weight


bool compareEdges(Edge a, Edge b) {
return a.weight < b.weight;
}
23350

// Kruskal's algorithm
void kruskalMST(Graph& graph) {
int V = graph.V;
vector<Edge> result; // To store the resulting MST
int e = 0; // Number of edges in MST

// Step 1: Sort all the edges by weight


sort(graph.edges.begin(), graph.edges.end(), compareEdges);

// Create subsets for union-find


vector<int> parent(V);
vector<int> rank(V, 0);

for (int i = 0; i < V; i++) {


parent[i] = i;
}

// Step 2: Pick edges one by one, ensuring no cycles


for (Edge& edge : graph.edges) {
if (e == V - 1) break;

int x = find(parent, edge.src);


int y = find(parent, edge.dest);

// If including this edge does not form a cycle


if (x != y) {
result.push_back(edge);
e++;
unionSets(parent, rank, x, y);
}
}

// Print the MST


cout << "Edges in the Minimum Spanning Tree:\n";
int totalWeight = 0;
for (Edge& edge : result) {
cout << edge.src << " -- " << edge.dest << " == " << edge.weight << "\n";
totalWeight += edge.weight;
}
cout << "Total weight of the MST: " << totalWeight << endl;
}

int main() {
int V = 4; // Number of vertices
int E = 5; // Number of edges
Graph graph;
graph.V = V;
graph.E = E;

// Adding edges to the graph


graph.edges = {
{0, 1, 10},
{0, 2, 6},
23350

{0, 3, 5},
{1, 3, 15},
{2, 3, 4}
};

kruskalMST(graph);

return 0;
}

2. WAP to implement Prim’s algorithm:-

#include <iostream>
#include <climits>

using namespace std;

// Function to find the vertex with the minimum key value


int minKey(int key[], bool inMST[], int V) {
int min = INT_MAX, minIndex;

for (int v = 0; v < V; v++) {


if (!inMST[v] && key[v] < min) {
min = key[v];
minIndex = v;
}
}
return minIndex;
}

// Function to print the MST and its total weight


void printMST(int parent[], int graph[][5], int V) {
cout << "Edges in the Minimum Spanning Tree:\n";
int totalWeight = 0;
for (int i = 1; i < V; i++) {
cout << parent[i] << " -- " << i << " == " << graph[i][parent[i]] << "\n";
totalWeight += graph[i][parent[i]];
}
cout << "Total weight of the MST: " << totalWeight << endl;
}

// Prim's Algorithm
void primMST(int graph[][5], int V) {
int parent[5]; // Array to store the MST
23350

int key[5]; // Key values to pick the minimum weight edge


bool inMST[5]; // To track vertices included in MST

// Initialize all keys as infinite and inMST as false


for (int i = 0; i < V; i++) {
key[i] = INT_MAX;
inMST[i] = false;
}

// Start from the first vertex


key[0] = 0;
parent[0] = -1; // Root node of the MST

for (int count = 0; count < V - 1; count++) {


// Pick the minimum key vertex not in MST
int u = minKey(key, inMST, V);
inMST[u] = true;

// Update key and parent for adjacent vertices


for (int v = 0; v < V; v++) {
if (graph[u][v] && !inMST[v] && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}

// Print the MST


printMST(parent, graph, V);
}

int main() {
int V = 5; // Number of vertices
int graph[5][5] = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}
};

primMST(graph, V);

return 0;
}
23350

3. WAP to find the shortest path from a source node to all other nodes in a
weighted graph:-

#include <iostream>
#include <climits>

using namespace std;

// Function to find the vertex with the minimum distance value


int minDistance(int dist[], bool visited[], int V) {
int min = INT_MAX, minIndex;

for (int v = 0; v < V; v++) {


if (!visited[v] && dist[v] < min) {
min = dist[v];
minIndex = v;
}
}
return minIndex;
}

// Function to implement Dijkstra's algorithm


void dijkstra(int graph[][5], int V, int src) {
int dist[5]; // Array to hold the shortest distances
bool visited[5]; // To track processed nodes

// Initialize all distances as infinite and visited[] as false


for (int i = 0; i < V; i++) {
dist[i] = INT_MAX;
visited[i] = false;
}

// Distance of the source vertex to itself is always 0


dist[src] = 0;

// Find shortest path for all vertices


for (int count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex not yet processed
int u = minDistance(dist, visited, V);
visited[u] = true;

// Update distance of adjacent vertices


for (int v = 0; v < V; v++) {
if (!visited[v] && graph[u][v] && dist[u] != INT_MAX
&& dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}

// Print the distances


23350

cout << "Vertex\tDistance from Source (" << src << ")\n";
for (int i = 0; i < V; i++) {
cout << i << "\t" << dist[i] << "\n";
}
}

int main() {
int V = 5; // Number of vertices
int graph[5][5] = {
{0, 10, 0, 0, 5},
{0, 0, 1, 0, 2},
{0, 0, 0, 4, 0},
{7, 0, 6, 0, 0},
{0, 3, 9, 2, 0}
};

int src = 0; // Source vertex


dijkstra(graph, V, src);

return 0;
}

4. WAP to find the shortest path from a source node to all other nodes in a weighted
graph using Dijkstra's algorithm:-

#include <iostream>
#include <climits>

using namespace std;

// Function to find the vertex with the minimum distance value


int minDistance(int dist[], bool visited[], int V) {
int min = INT_MAX, minIndex;

for (int v = 0; v < V; v++) {


if (!visited[v] && dist[v] < min) {
min = dist[v];
minIndex = v;
}
}
return minIndex;
}

// Function to implement Dijkstra's algorithm


void dijkstra(int graph[][6], int V, int src) {
int dist[V]; // Array to hold the shortest distances
23350

bool visited[V]; // To track processed nodes

// Initialize all distances as infinite and visited[] as false


for (int i = 0; i < V; i++) {
dist[i] = INT_MAX;
visited[i] = false;
}

// Distance of the source vertex to itself is always 0


dist[src] = 0;

// Find the shortest path for all vertices


for (int count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex not yet processed
int u = minDistance(dist, visited, V);
visited[u] = true;

// Update distance of adjacent vertices


for (int v = 0; v < V; v++) {
if (!visited[v] && graph[u][v] && dist[u] != INT_MAX
&& dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}

// Print the distances


cout << "Vertex\tDistance from Source (" << src << ")\n";
for (int i = 0; i < V; i++) {
cout << i << "\t" << dist[i] << "\n";
}
}

int main() {
int V = 6; // Number of vertices
int graph[6][6] = {
{0, 4, 0, 0, 0, 0},
{4, 0, 8, 0, 0, 0},
{0, 8, 0, 7, 0, 4},
{0, 0, 7, 0, 9, 14},
{0, 0, 0, 9, 0, 10},
{0, 0, 4, 14, 10, 0}
};

int src = 0; // Source vertex


dijkstra(graph, V, src);

return 0;
}
23350

5. WAP to find the shortest path from a source node to all other nodes in a
weighted graph using Floyd- Warshall Algorithm:-

#include <iostream>
#include <climits>

using namespace std;

#define INF INT_MAX // Define infinity as a large value

// Function to print the distance matrix


void printSolution(int dist[][4], int V) {
cout << "Shortest distances between every pair of vertices:\n";
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INF)
cout << "INF\t";
else
cout << dist[i][j] << "\t";
}
cout << endl;
}
}

// Floyd-Warshall Algorithm
void floydWarshall(int graph[][4], int V) {
int dist[4][4];

// Initialize the solution matrix same as the input graph matrix


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = graph[i][j];
}
}

// Update distances by considering each vertex as an intermediate


for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
// Safeguard against overflow
if (dist[i][k] != INF && dist[k][j] != INF
&& dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
23350

// Print the solution


printSolution(dist, V);
}

int main() {
int V = 4; // Number of vertices
int graph[4][4] = {
{0, 3, INF, 7},
{8, 0, 2, INF},
{5, INF, 0, 1},
{2, INF, INF, 0}
};

floydWarshall(graph, V);

return 0;
}

6. Determine a topological ordering of nodes in a directed acyclic graph, and what


applications benefit from topological sorting:-

➢ Code:-

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

// Function to perform topological sorting


void topologicalSort(int V, vector<int> adj[]) {
vector<int> inDegree(V, 0); // Array to store in-degrees
vector<int> topoOrder; // Vector to store topological order
queue<int> q; // Queue for processing vertices

// Calculate in-degrees of all vertices


for (int i = 0; i < V; i++) {
for (int v : adj[i]) {
inDegree[v]++;
}
}

// Enqueue vertices with in-degree 0


for (int i = 0; i < V; i++) {
23350

if (inDegree[i] == 0) {
q.push(i);
}
}

// Process the vertices in topological order


while (!q.empty()) {
int u = q.front();
q.pop();
topoOrder.push_back(u);

// Decrease in-degree of adjacent vertices


for (int v : adj[u]) {
inDegree[v]--;
if (inDegree[v] == 0) {
q.push(v);
}
}
}

// Check if there was a cycle


if (topoOrder.size() != V) {
cout << "The graph is not a DAG (contains a cycle)." << endl;
return;
}

// Print topological order


cout << "Topological Order: ";
for (int v : topoOrder) {
cout << v << " ";
}
cout << endl;
}

int main() {
int V = 6; // Number of vertices
vector<int> adj[V]; // Adjacency list representation

// Add edges to the graph


adj[5].push_back(2);
adj[5].push_back(0);
adj[4].push_back(0);
adj[4].push_back(1);
adj[2].push_back(3);
adj[3].push_back(1);

topologicalSort(V, adj);

return 0;
}
23350

➢ Applications of Topological Sorting:-

i) Task Scheduling:-
• Dependency resolution between tasks (e.g., job scheduling, build
systems like Make).
• Example: Build order of software components with dependencies.
ii) Course Scheduling:-
• Determining the order in which courses should be taken given
prerequisites.
iii) Critical Path Method (CPM):-
• In project management, to find the sequence of tasks that determines
the project duration.
iv) Dependency Management:-
• Package management systems (e.g., resolving installation order of
libraries or modules).
v) Compiler Design:-
• Order of compilation for modules with dependencies.
vi) Data Serialization:-
• Determining the order in which objects need to be saved or loaded
while preserving dependencies.

7. Try: WAP to check if a graph is bipartite, and what does it mean for a graph to
be bipartite in terms of graph coloring:-

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

// Function to check if the graph is bipartite using BFS


bool isBipartite(vector<int> adj[], int V) {
vector<int> color(V, -1); // -1 indicates uncolored vertices

// Check for each component of the graph


for (int start = 0; start < V; start++) {
if (color[start] == -1) { // Unvisited node
queue<int> q;
23350

q.push(start);
color[start] = 0; // Start coloring with 0

while (!q.empty()) {
int u = q.front();
q.pop();

for (int v : adj[u]) {


if (color[v] == -1) {
// Assign alternate color to adjacent vertex
color[v] = 1 - color[u];
q.push(v);
} else if (color[v] == color[u]) {
// If adjacent vertex has the same color, graph is not bipartite
return false;
}
}
}
}
}
return true; // Graph is bipartite
}

int main() {
int V = 6; // Number of vertices
vector<int> adj[V]; // Adjacency list representation

// Add edges to the graph


adj[0].push_back(1);
adj[1].push_back(0);
adj[1].push_back(2);
adj[2].push_back(1);
adj[2].push_back(3);
adj[3].push_back(2);
adj[3].push_back(4);
adj[4].push_back(3);
adj[4].push_back(5);
adj[5].push_back(4);

// Check if the graph is bipartite


if (isBipartite(adj, V)) {
cout << "The graph is bipartite." << endl;
} else {
cout << "The graph is not bipartite." << endl;
}

return 0;
}
23350

➢ Key Points About Bipartite Graphs in Terms of Coloring:-

i) 2-Colorable: A bipartite graph can be colored using two colors such that
no two adjacent vertices share the same color.
ii) No Odd Cycles: A graph is bipartite if and only if it does not contain any
odd-length cycles.
iii) Vertex Partition: The vertices can be partitioned into two disjoint sets
such that every edge connects vertices from different sets.
8. Try: Given a grid where 1 represents open cells and 0 represents walls, find the
shortest path from a start cell to an end cell:-
Hint: Use BFS for shortest paths in unweighted grids and practice navigating 2D
grids.

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

// Directions for moving in the grid (up, down, left, right)


int rowDir[] = {-1, 1, 0, 0};
int colDir[] = {0, 0, -1, 1};

// Function to check if a cell is valid (inside the grid and not a wall)
bool isValid(int x, int y, int rows, int cols, vector<vector<int>>& grid,
vector<vector<bool>>& visited) {
return x >= 0 && x < rows && y >= 0 && y < cols && grid[x][y] == 1 && !visited[x][y];
}

// Function to find the shortest path from start to end in a grid


int shortestPath(vector<vector<int>>& grid, pair<int, int> start, pair<int, int> end) {
int rows = grid.size();
int cols = grid[0].size();

// Create a visited array to track visited cells


vector<vector<bool>> visited(rows, vector<bool>(cols, false));

// Queue for BFS: stores (x, y) coordinates and number of steps


queue<pair<pair<int, int>, int>> q; // ((x, y), distance)

// Start BFS from the start cell


q.push({start, 0}); // Start cell with distance 0
visited[start.first][start.second] = true;

while (!q.empty()) {
auto current = q.front();
q.pop();

int x = current.first.first;
int y = current.first.second;
int dist = current.second;
23350

// If we reach the end cell, return the distance


if (x == end.first && y == end.second) {
return dist;
}

// Explore the 4 possible directions (up, down, left, right)


for (int i = 0; i < 4; i++) {
int newX = x + rowDir[i];
int newY = y + colDir[i];

// Check if the new position is valid


if (isValid(newX, newY, rows, cols, grid, visited)) {
visited[newX][newY] = true;
q.push({{newX, newY}, dist + 1});
}
}
}

// If no path exists
return -1;
}

int main() {
// Example grid
vector<vector<int>> grid = {
{1, 1, 1, 0, 0},
{1, 0, 1, 0, 1},
{1, 0, 1, 1, 1},
{0, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
};

// Start and end coordinates


pair<int, int> start = {0, 0}; // Start cell (row 0, column 0)
pair<int, int> end = {4, 4}; // End cell (row 4, column 4)

// Find the shortest path


int result = shortestPath(grid, start, end);

// Output result
if (result != -1) {
cout << "The shortest path length is: " << result << endl;
} else {
cout << "No path exists from start to end." << endl;
}

return 0;

You might also like