Professional Documents
Culture Documents
Assignment 5
Assignment 5
Part 1:
1)Depth first search using adjacency matrix:
#include <bits/stdc++.h>
adj[x][y] = 1;
adj[y][x] = 1;
visited[start] = true;
dfs(i, visited);
int main()
{
int v = 5;
int e = 4;
addEdge(0, 1);
addEdge(0, 2);
addEdge(0, 3);
addEdge(0, 4);
dfs(0, visited);
#include <iostream>
#include <vector>
class Graph
int vertex_count;
int id;
Color color;
color(Color::WHITE)
{}
};
struct Adj_list_node
int dest_id;
Adj_list_node * next;
next (nullptr)
{}
};
struct Adj_list
Adj_list_node *head;
};
std::vector<Vertex> vertices;
std::vector<Adj_list> adjacent;
public:
Graph(int);
void depth_first_search();
private:
void depth_first_search_visit(int);
};
Graph::Graph(int v)
vertex_count = v;
adjacent.resize(vertex_count);
vertices.push_back( Vertex(i) );
adjacent[i].head = nullptr;
void Graph::depth_first_search()
if (vertices[u.id].color == WHITE)
depth_first_search_visit(u.id);
void Graph::depth_first_search_visit(int u)
vertices[u].color = GRAY;
std::cout << vertices[u].id <<" ";
if (vertices[v->dest_id].color == WHITE)
depth_first_search_visit(v->dest_id);
vertices[u].color = BLACK;
if (adjacent[src].head == nullptr)
adjacent[src].head = node;
else
tmp = tmp->next;
tmp->next = node;
//undirected graph
if (adjacent[dest].head == nullptr)
adjacent[dest].head = node;
}
else
tmp = tmp->next;
tmp->next = node;
int main()
Graph grp(4);
grp.add_edge(0, 1);
grp.add_edge(1, 2);
grp.add_edge(2, 3);
grp.add_edge(2, 1);
grp.add_edge(0, 3);
grp.depth_first_search();
Depth First Search has a time complexity of O(b^m), where b is the maximum branching factor of the
search tree and m is the maximum depth of the state space and The space complexity is O(bm).
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> adj;
adj[x][y] = 1;
adj[y][x] = 1;
vector<int> q;
q.push_back(start);
visited[start] = true;
int vis;
while (!q.empty()) {
vis = q[0];
q.erase(q.begin());
q.push_back(i);
visited[i] = true;
int main()
int v = 5;
adj= vector<vector<int>>(v,vector<int>(v,0));
addEdge(0,1);
addEdge(0,2);
addEdge(1,3);
bfs(0);
#include <iostream>
#include <queue>
#include <vector>
#define N 5
class Graph {
public:
vector<int> adj_[N];
adj_[u].push_back(v);
adj_[v].push_back(u);
queue<int> q;
q.push(src);
visited[src] = true;
distance[src] = 0;
vector<int> path;
while (!q.empty()) {
int u = q.front();
q.pop();
path.push_back(u);
if (!visited[v]) {
q.push(v);
visited[v] = true;
distance[v] = distance[u] + 1;
cout << "Breadth First Traversal: starting from vertex: " << src << endl;
cout << "Distance of nodes from : " << src << endl;
cout << "to node " << i << " -> " << distance[i] << endl;
};
int main() {
Graph g;
g.addEdge(0, 3);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.bfs(0);
where b – maximum branching factor of the search tree d – depth of the least-cost solution
#include <iostream>
#include <limits.h>
#include <list>
using namespace std;
class Graph {
// No. of vertices
int V;
// Pointer to an array
list<int>* adj;
public:
// Constructor
Graph(int V);
bool isCyclic();
};
Graph::Graph(int V)
this->V = V;
adj[v].push_back(w);
adj[w].push_back(v);
// from vertex v.
visited[v] = true;
list<int>::iterator i;
if (!visited[*i]) {
return true;
}
// If an adjacent vertex is visited and
return true;
return false;
bool Graph::isCyclic()
// stack
visited[i] = false;
// DFS trees
// it is already visited
if (!visited[u])
return true;
}
return false;
int main()
Graph g1(5);
g1.addEdge(1, 0);
g1.addEdge(0, 2);
g1.addEdge(2, 1);
g1.addEdge(0, 3);
g1.addEdge(3, 4);
Graph g2(3);
g2.addEdge(0, 1);
g2.addEdge(1, 2);
return 0;
}
Detecting cycles using adjacency list:
#include<bits/stdc++.h>
class Graph
public:
};
Graph::Graph(int V)
this->V = V;
// https://www.geeksforgeeks.org/archives/18212
{
if(visited[v] == false)
visited[v] = true;
recStack[v] = true;
list<int>::iterator i;
return true;
else if (recStack[*i])
return true;
return false;
// https://www.geeksforgeeks.org/archives/18212
bool Graph::isCyclic()
// Mark all the vertices as not visited and not part of recursion
// stack
visited[i] = false;
recStack[i] = false;
// DFS trees
return true;
return false;
int main()
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
if(g.isCyclic())
else
return 0;
}
We are traversing through all the nodes and edges. So time complexity will be O(V + E) where V =
vertices or node, E = edges.
We use a visited array, recursion stack array and an adjacency list for the graph. So the space
complexity will be O(V) + O(V) + O(V + E) + extra space for the recursion calls.
#include <bits/stdc++.h>
class Graph {
// No. of vertices'
int V;
list<int>* adj;
stack<int>& Stack);
public:
// Constructor
Graph(int V);
// function to add an edge to graph
void topologicalSort();
};
Graph::Graph(int V)
this->V = V;
adj[v].push_back(w);
stack<int>& Stack)
{
// Mark the current node as visited.
visited[v] = true;
list<int>::iterator i;
if (!visited[*i])
Stack.push(v);
void Graph::topologicalSort()
stack<int> Stack;
visited[i] = false;
// Call the recursive helper function
// to store Topological
if (visited[i] == false)
Stack.pop();
delete [] visited;
// Driver Code
int main()
Graph g(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
"graph \n";
// Function Call
g.topologicalSort();
return 0;
}
Time and Space Complexity for Topological Sort The time complexity for the Topological Sort
Algorithm is O (V+E) where “V” and “E” are the numbers of vertices and edges of the graph
respectively. We need to traverse all nodes of the graph for implementation.
#include<iomanip>
#define NODE 7
int costMat[NODE][NODE] = {
{6, 2, 0, 1, 4, 2, INF},
};
void floydWarshal(){
int cost[NODE][NODE]; //defind to store shortest distance from any node to any node
cost[i][j] = cost[i][k]+cost[k][j];
int main(){
floydWarshal();
}
Single-source shortest path is solved by the Bellman-Ford algorithm, with a time complexity of O
(VE). All-pairs shortest path can be solved using Johnson's algorithm in O (EV + V 2 log V) time.
Additionally, there is the Floyd-Warshall algorithm, which solves it in O (V 3): this is typically faster
on dense graphs.
#include<stdio.h>
#define V 4
int reach[V][V], i, j, k;
reach[i][j] = graph[i][j];
{
for (i = 0; i < V; i++)
reach[i][j] = reach[i][j] ||
printSolution(reach);
if(i == j)
printf("1 ");
else
printf("\n");
}
// Driver Code
int main()
{0, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1}
};
transitiveClosure(graph);
return 0;
The time complexity of computing the transitive closure of a binary relation on a set of n elements
is O (n3). Apply the Warshall's algorithm to compute the transitive closure. The algorithm contains
three nested for loops each having frequency n so time complexity is O (n3).
Part 2:
1)Dijkstra's shortest path algorithm using adjacency list:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct AdjListNode
int dest;
int weight;
};
struct AdjList
};
struct Graph
int V;
};
(struct AdjListNode*)
malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->weight = weight;
newNode->next = NULL;
return newNode;
malloc(sizeof(struct Graph));
graph->V = V;
graph->array[i].head = NULL;
return graph;
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
struct MinHeapNode
int v;
int dist;
};
struct MinHeap
int size;
int capacity;
int *pos;
int dist)
(struct MinHeapNode*)
malloc(sizeof(struct MinHeapNode));
minHeapNode->v = v;
minHeapNode->dist = dist;
return minHeapNode;
(struct MinHeap*)
malloc(sizeof(struct MinHeap));
capacity * sizeof(int));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array =
(struct MinHeapNode**)
malloc(capacity *
sizeof(struct MinHeapNode*));
return minHeap;
}
void swapMinHeapNode(struct MinHeapNode** a,
struct MinHeapNode** b)
*a = *b;
*b = t;
int idx)
smallest = idx;
left = 2 * idx + 1;
right = 2 * idx + 2;
minHeap->array[left]->dist <
minHeap->array[smallest]->dist )
smallest = left;
minHeap->array[right]->dist <
minHeap->array[smallest]->dist )
smallest = right;
if (smallest != idx)
MinHeapNode *smallestNode =
minHeap->array[smallest];
MinHeapNode *idxNode =
minHeap->array[idx];
// Swap positions
minHeap->pos[smallestNode->v] = idx;
minHeap->pos[idxNode->v] = smallest;
// Swap nodes
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
return minHeap->size == 0;
minHeap)
if (isEmpty(minHeap))
return NULL;
// Store the root node
minHeap->array[0];
minHeap->array[minHeap->size - 1];
minHeap->array[0] = lastNode;
minHeap->pos[root->v] = minHeap->size-1;
minHeap->pos[lastNode->v] = 0;
--minHeap->size;
minHeapify(minHeap, 0);
return root;
int i = minHeap->pos[v];
minHeap->array[i]->dist = dist;
minHeap->array[(i - 1) / 2]->dist)
{
minHeap->pos[minHeap->array[i]->v] =
(i-1)/2;
minHeap->pos[minHeap->array[
(i-1)/2]->v] = i;
swapMinHeapNode(&minHeap->array[i],
&minHeap->array[(i - 1) / 2]);
i = (i - 1) / 2;
return true;
return false;
}
// The main function that calculates
int V = graph->V;
int dist[V];
dist[v] = INT_MAX;
minHeap->array[v] = newMinHeapNode(v,
dist[v]);
minHeap->pos[v] = v;
minHeap->array[src] =
newMinHeapNode(src, dist[src]);
minHeap->pos[src] = src;
dist[src] = 0;
minHeap->size = V;
while (!isEmpty(minHeap))
extractMin(minHeap);
int u = minHeapNode->v;
graph->array[u].head;
int v = pCrawl->dest;
// If shortest distance to v is
// not finalized yet, and distance to v
if (isInMinHeap(minHeap, v) &&
// update distance
decreaseKey(minHeap, v, dist[v]);
pCrawl = pCrawl->next;
printArr(dist, V);
int main()
int V = 9;
addEdge(graph, 0, 1, 4);
addEdge(graph, 0, 7, 8);
addEdge(graph, 1, 2, 8);
addEdge(graph, 1, 7, 11);
addEdge(graph, 2, 3, 7);
addEdge(graph, 2, 8, 2);
addEdge(graph, 2, 5, 4);
addEdge(graph, 3, 4, 9);
addEdge(graph, 3, 5, 14);
addEdge(graph, 4, 5, 10);
addEdge(graph, 5, 6, 2);
addEdge(graph, 6, 7, 1);
addEdge(graph, 6, 8, 6);
addEdge(graph, 7, 8, 7);
dijkstra(graph, 0);
return 0;
Dijkstra Algorithm is a graph algorithm for finding the shortest path from a source node to all other
nodes in a graph (single-source shortest path). It is a type of greedy algorithm. It only works on
weighted graphs with positive weights. It has a time complexity of O (V^2) O(V 2) using the
adjacency matrix representation of graph.
2) Bellman-Ford algorithm:
#include <bits/stdc++.h>
using namespace std;
int src)
int dis[V];
dis[i] = INT_MAX;
dis[src] = 0;
dis[graph[j][1]])
dis[graph[j][1]] =
dis[graph[j][0]] + graph[j][2];
int x = graph[i][0];
int y = graph[i][1];
<< endl;
int main()
int graph[][3] = { { 0, 1, -1 }, { 0, 2, 4 },
{ 1, 2, 3 }, { 1, 3, 2 },
{ 1, 4, 2 }, { 3, 2, 5 },
{ 3, 1, 1 }, { 4, 3, -3 } };
BellmanFord(graph, V, E, 0);
return 0;
}
Time Complexity : O(E V) = O(|V|2) * O(|V|) = O(V3)
3) Connected components:
#include <bits/stdc++.h>
class Graph {
list<int>* adj;
public:
Graph(int V); // Constructor
~Graph();
void connectedComponents();
};
void Graph::connectedComponents()
visited[v] = false;
if (visited[v] == false) {
// from v
DFSUtil(v, visited);
}
delete[] visited;
visited[v] = true;
list<int>::iterator i;
if (!visited[*i])
DFSUtil(*i, visited);
Graph::Graph(int V)
this->V = V;
}
Graph::~Graph() { delete[] adj; }
adj[v].push_back(w);
adj[w].push_back(v);
// Driver code
int main()
g.addEdge(1, 0);
g.addEdge(2, 1);
g.addEdge(3, 4);
g.connectedComponents();
return 0;
4) Prim’s algorithm:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
struct AdjListNode {
int dest;
int weight;
};
struct AdjList {
struct AdjListNode*
// vertices in graph)
struct Graph {
int V;
};
= (struct AdjListNode*)malloc(
sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->weight = weight;
newNode->next = NULL;
return newNode;
}
// A utility function that creates a graph of V vertices
graph->V = V;
// will be V
V * sizeof(struct AdjList));
// head as NULL
graph->array[i].head = NULL;
return graph;
// beginning
= newAdjListNode(dest, weight);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
// src also
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
struct MinHeapNode {
int v;
int key;
};
// Structure to represent a min heap
struct MinHeap {
};
= (struct MinHeapNode*)malloc(
sizeof(struct MinHeapNode));
minHeapNode->v = v;
minHeapNode->key = key;
return minHeapNode;
minHeap->size = 0;
minHeap->capacity = capacity;
return minHeap;
struct MinHeapNode** b)
*a = *b;
*b = t;
smallest = idx;
left = 2 * idx + 1;
right = 2 * idx + 2;
&& minHeap->array[left]->key
< minHeap->array[smallest]->key)
smallest = left;
&& minHeap->array[right]->key
< minHeap->array[smallest]->key)
smallest = right;
if (smallest != idx) {
MinHeapNode* smallestNode
= minHeap->array[smallest];
// Swap positions
minHeap->pos[smallestNode->v] = idx;
minHeap->pos[idxNode->v] = smallest;
// Swap nodes
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
// or not
return minHeap->size == 0;
}
// Standard function to extract minimum node from heap
if (isEmpty(minHeap))
return NULL;
= minHeap->array[minHeap->size - 1];
minHeap->array[0] = lastNode;
minHeap->pos[root->v] = minHeap->size - 1;
minHeap->pos[lastNode->v] = 0;
--minHeap->size;
minHeapify(minHeap, 0);
return root;
int i = minHeap->pos[v];
minHeap->array[i]->key = key;
while (i
&& minHeap->array[i]->key
minHeap->pos[minHeap->array[i]->v] = (i - 1) / 2;
minHeap->pos[minHeap->array[(i - 1) / 2]->v] = i;
swapMinHeapNode(&minHeap->array[i],
&minHeap->array[(i - 1) / 2]);
i = (i - 1) / 2;
return true;
return false;
// edge in cut
// infinite
parent[v] = -1;
key[v] = INT_MAX;
minHeap->pos[v] = v;
}
// is extracted first
key[0] = 0;
minHeap->pos[0] = 0;
minHeap->size = V;
while (!isEmpty(minHeap)) {
= extractMin(minHeap);
int u
= minHeapNode
int v = pCrawl->dest;
if (isInMinHeap(minHeap, v)
key[v] = pCrawl->weight;
parent[v] = u;
decreaseKey(minHeap, v, key[v]);
pCrawl = pCrawl->next;
printArr(parent, V);
}
// Driver program to test above functions
int main()
int V = 9;
addEdge(graph, 0, 1, 4);
addEdge(graph, 0, 7, 8);
addEdge(graph, 1, 2, 8);
addEdge(graph, 1, 7, 11);
addEdge(graph, 2, 3, 7);
addEdge(graph, 2, 8, 2);
addEdge(graph, 2, 5, 4);
addEdge(graph, 3, 4, 9);
addEdge(graph, 3, 5, 14);
addEdge(graph, 4, 5, 10);
addEdge(graph, 5, 6, 2);
addEdge(graph, 6, 7, 1);
addEdge(graph, 6, 8, 6);
addEdge(graph, 7, 8, 7);
PrimMST(graph);
return 0;
5) Kruskal’s algorithm:
#include <bits/stdc++.h>
#define V 5
int parent[V];
int find(int i)
while (parent[i] != i)
i = parent[i];
return i;
}
int a = find(i);
int b = find(j);
parent[a] = b;
parent[i] = i;
int edge_count = 0;
min = cost[i][j];
a = i;
b = j;
union1(a, b);
edge_count++, a, b, min);
mincost += min;
int main()
{
int cost[][V] = {
{ 2, INT_MAX, 3, 8, 5 },
{ 6, 8, INT_MAX, INT_MAX, 9 },
{ INT_MAX, 5, 7, 9, INT_MAX },
};
kruskalMST(cost);
return 0;