Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 64

ASSIGNMENT 5:

Part 1:
1)Depth first search using adjacency matrix:

#include <bits/stdc++.h>

using namespace std;

vector<vector<int> > adj;

void addEdge(int x, int y)

adj[x][y] = 1;

adj[y][x] = 1;

void dfs(int start, vector<bool>& visited)

cout << start << " ";

visited[start] = true;

for (int i = 0; i < adj[start].size(); i++) {

if (adj[start][i] == 1 && (!visited[i])) {

dfs(i, visited);

int main()
{

int v = 5;

int e = 4;

adj = vector<vector<int> >(v, vector<int>(v, 0));

addEdge(0, 1);

addEdge(0, 2);

addEdge(0, 3);

addEdge(0, 4);

vector<bool> visited(v, false);

dfs(0, visited);

Depth first search using adjacency list:

#include <iostream>

#include <vector>

class Graph

int vertex_count;

enum Color {WHITE, GRAY, BLACK};


struct Vertex

int id;

Color color;

Vertex(int _id) : id(_id),

color(Color::WHITE)

{}

};

struct Adj_list_node

int dest_id;

Adj_list_node * next;

Adj_list_node(int _dest_id) : dest_id(_dest_id),

next (nullptr)

{}

};

struct Adj_list

Adj_list_node *head;

};

std::vector<Vertex> vertices;

std::vector<Adj_list> adjacent;

public:

Graph(int);

void add_edge(int, int);

void depth_first_search();
private:

void depth_first_search_visit(int);

};

Graph::Graph(int v)

vertex_count = v;

adjacent.resize(vertex_count);

for (int i = 0; i < vertex_count; i++)

vertices.push_back( Vertex(i) );

adjacent[i].head = nullptr;

void Graph::depth_first_search()

for (const auto& u: vertices)

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 <<" ";

const auto& v = adjacent[u].head;

if (vertices[v->dest_id].color == WHITE)

depth_first_search_visit(v->dest_id);

vertices[u].color = BLACK;

void Graph::add_edge(int src, int dest)

Adj_list_node *node = new Adj_list_node(dest);

if (adjacent[src].head == nullptr)

adjacent[src].head = node;

else

Adj_list_node *tmp = adjacent[src].head;

while (tmp->next != nullptr)

tmp = tmp->next;

tmp->next = node;

//undirected graph

node = new Adj_list_node(src);

if (adjacent[dest].head == nullptr)

adjacent[dest].head = node;

}
else

Adj_list_node *tmp = adjacent[dest].head;

while (tmp->next != nullptr)

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();

std::cout << "\n";

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).

2) Breadth first search using adjacency matrix:

#include<bits/stdc++.h>
using namespace std;

vector<vector<int>> adj;

void addEdge(int x,int y)

adj[x][y] = 1;

adj[y][x] = 1;

void bfs(int start)

vector<bool> visited(adj.size(), false);

vector<int> q;

q.push_back(start);

visited[start] = true;

int vis;

while (!q.empty()) {

vis = q[0];

cout << vis << " ";

q.erase(q.begin());

for (int i = 0; i < adj[vis].size(); i++) {

if (adj[vis][i] == 1 && (!visited[i])) {

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);

Breadth first search using adjacency list:

#include <iostream>

#include <queue>

#include <vector>

using namespace std;

#define N 5

class Graph {
public:

vector<int> adj_[N];

void addEdge(int u, int v) {

// In case of undirected graph, to and fro traversal is allowed

adj_[u].push_back(v);

adj_[v].push_back(u);

void bfs(int src) {

vector<bool> visited(N, false);

vector<int> distance(N, 0);

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);

for (auto v : adj_[u]) {

if (!visited[v]) {

q.push(v);

visited[v] = true;

distance[v] = distance[u] + 1;

cout << "Breadth First Traversal: starting from vertex: " << src << endl;

for (auto d : path) cout << d << " ";


cout << endl;

cout << "Distance of nodes from : " << src << endl;

for (int i = 0; i < distance.size(); i++)

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);

Time complexity: Total numb. of nodes generated: 1 + b + b2 + … + bd + b(b^d-1) = O(b^(d+1)) Space


complexity:O(b^(d+1))

where b – maximum branching factor of the search tree d – depth of the least-cost solution

3) Detecting cycles using adjacency matrix:

#include <iostream>

#include <limits.h>

#include <list>
using namespace std;

// Class for an undirected graph

class Graph {

// No. of vertices

int V;

// Pointer to an array

// containing adjacency lists

list<int>* adj;

bool isCyclicUtil(int v, bool visited[], int parent);

public:

// Constructor

Graph(int V);

// To add an edge to graph

void addEdge(int v, int w);

// Returns true if there is a cycle

bool isCyclic();

};

Graph::Graph(int V)

this->V = V;

adj = new list<int>[V];

void Graph::addEdge(int v, int w)


{

// Add w to v’s list.

adj[v].push_back(w);

// Add v to w’s list.

adj[w].push_back(v);

// A recursive function that

// uses visited[] and parent to detect

// cycle in subgraph reachable

// from vertex v.

bool Graph::isCyclicUtil(int v, bool visited[], int parent)

// Mark the current node as visited

visited[v] = true;

// Recur for all the vertices

// adjacent to this vertex

list<int>::iterator i;

for (i = adj[v].begin(); i != adj[v].end(); ++i) {

// If an adjacent vertex is not visited,

// then recur for that adjacent

if (!visited[*i]) {

if (isCyclicUtil(*i, visited, v))

return true;

}
// If an adjacent vertex is visited and

// is not parent of current vertex,

// then there exists a cycle in the graph.

else if (*i != parent)

return true;

return false;

// Returns true if the graph contains

// a cycle, else false.

bool Graph::isCyclic()

// Mark all the vertices as not

// visited and not part of recursion

// stack

bool* visited = new bool[V];

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

visited[i] = false;

// Call the recursive helper

// function to detect cycle in different

// DFS trees

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

// Don't recur for u if

// it is already visited

if (!visited[u])

if (isCyclicUtil(u, visited, -1))

return true;
}

return false;

// Driver program to test above functions

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);

g1.isCyclic() ? cout << "Graph contains cycle\n"

: cout << "Graph doesn't contain cycle\n";

Graph g2(3);

g2.addEdge(0, 1);

g2.addEdge(1, 2);

g2.isCyclic() ? cout << "Graph contains cycle\n"

: cout << "Graph doesn't contain cycle\n";

return 0;

}
Detecting cycles using adjacency list:

#include<bits/stdc++.h>

using namespace std;

class Graph

int V; // No. of vertices

list<int> *adj; // Pointer to an array containing adjacency lists

bool isCyclicUtil(int v, bool visited[], bool *rs); // used by isCyclic()

public:

Graph(int V); // Constructor

void addEdge(int v, int w); // to add an edge to graph

bool isCyclic(); // returns true if there is a cycle in this graph

};

Graph::Graph(int V)

this->V = V;

adj = new list<int>[V];

void Graph::addEdge(int v, int w)

adj[v].push_back(w); // Add w to v’s list.

// This function is a variation of DFSUtil() in

// https://www.geeksforgeeks.org/archives/18212

bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack)

{
if(visited[v] == false)

// Mark the current node as visited and part of recursion stack

visited[v] = true;

recStack[v] = true;

// Recur for all the vertices adjacent to this vertex

list<int>::iterator i;

for(i = adj[v].begin(); i != adj[v].end(); ++i)

if ( !visited[*i] && isCyclicUtil(*i, visited, recStack) )

return true;

else if (recStack[*i])

return true;

recStack[v] = false; // remove the vertex from recursion stack

return false;

// Returns true if the graph contains a cycle, else false.

// This function is a variation of DFS() in

// https://www.geeksforgeeks.org/archives/18212

bool Graph::isCyclic()

// Mark all the vertices as not visited and not part of recursion

// stack

bool *visited = new bool[V];

bool *recStack = new bool[V];

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


{

visited[i] = false;

recStack[i] = false;

// Call the recursive helper function to detect cycle in different

// DFS trees

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

if ( !visited[i] && isCyclicUtil(i, visited, recStack))

return true;

return false;

int main()

// Create a graph given in the above diagram

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())

cout << "Graph contains cycle";

else

cout << "Graph doesn't contain cycle";

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.

4) Topological sort using adjacence matrix:

#include <bits/stdc++.h>

using namespace std;

// Class to represent a graph

class Graph {

// No. of vertices'

int V;

// Pointer to an array containing adjacency listsList

list<int>* adj;

// A function used by topologicalSort

void topologicalSortUtil(int v, bool visited[],

stack<int>& Stack);

public:

// Constructor

Graph(int V);
// function to add an edge to graph

void addEdge(int v, int w);

// prints a Topological Sort of

// the complete graph

void topologicalSort();

};

Graph::Graph(int V)

this->V = V;

adj = new list<int>[V];

void Graph::addEdge(int v, int w)

// Add w to v’s list.

adj[v].push_back(w);

// A recursive function used by topologicalSort

void Graph::topologicalSortUtil(int v, bool visited[],

stack<int>& Stack)

{
// Mark the current node as visited.

visited[v] = true;

// Recur for all the vertices

// adjacent to this vertex

list<int>::iterator i;

for (i = adj[v].begin(); i != adj[v].end(); ++i)

if (!visited[*i])

topologicalSortUtil(*i, visited, Stack);

// Push current vertex to stack

// which stores result

Stack.push(v);

// The function to do Topological Sort.

// It uses recursive topologicalSortUtil()

void Graph::topologicalSort()

stack<int> Stack;

// Mark all the vertices as not visited

bool* visited = new bool[V];

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

visited[i] = false;
// Call the recursive helper function

// to store Topological

// Sort starting from all

// vertices one by one

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

if (visited[i] == false)

topologicalSortUtil(i, visited, Stack);

// Print contents of stack

while (Stack.empty() == false) {

cout << Stack.top() << " ";

Stack.pop();

delete [] visited;

// Driver Code

int main()

// Create a graph given in the above diagram

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);

cout << "Following is a Topological Sort of the given "

"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.

5) All pairs shortest paths:


#include<iostream>

#include<iomanip>

#define NODE 7

#define INF 999

using namespace std;

//Cost matrix of the graph

int costMat[NODE][NODE] = {

{0, 3, 6, INF, INF, INF, INF},


{3, 0, 2, 1, INF, INF, INF},

{6, 2, 0, 1, 4, 2, INF},

{INF, 1, 1, 0, 2, INF, 4},

{INF, INF, 4, 2, 0, 2, 1},

{INF, INF, 2, INF, 2, 0, 1},

{INF, INF, INF, 4, 1, 1, 0}

};

void floydWarshal(){

int cost[NODE][NODE]; //defind to store shortest distance from any node to any node

for(int i = 0; i<NODE; i++)

for(int j = 0; j<NODE; j++)

cost[i][j] = costMat[i][j]; //copy costMatrix to new matrix

for(int k = 0; k<NODE; k++){

for(int i = 0; i<NODE; i++)

for(int j = 0; j<NODE; j++)

if(cost[i][k]+cost[k][j] < cost[i][j])

cost[i][j] = cost[i][k]+cost[k][j];

cout << "The matrix:" << endl;

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

for(int j = 0; j<NODE; j++)

cout << setw(3) << cost[i][j];

cout << endl;

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.

6) Transitive closure of a binary relation:

#include<stdio.h>

#define V 4

void printSolution(int reach[][V]);

void transitiveClosure(int graph[][V])

int reach[V][V], i, j, k;

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

for (j = 0; j < V; j++)

reach[i][j] = graph[i][j];

for (k = 0; k < V; k++)

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

for (j = 0; j < V; j++)

reach[i][j] = reach[i][j] ||

(reach[i][k] && reach[k][j]);

printSolution(reach);

void printSolution(int reach[][V])

printf ("Following matrix is transitive");

printf("closure of the given graph\n");

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

for (int j = 0; j < V; j++)

if(i == j)

printf("1 ");

else

printf ("%d ", reach[i][j]);

printf("\n");
}

// Driver Code

int main()

int graph[V][V] = { {1, 1, 0, 1},

{0, 1, 1, 0},

{0, 0, 1, 1},

{0, 0, 0, 1}

};

// Print the solution

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 AdjListNode* next;

};

struct AdjList

struct AdjListNode *head;

};

struct Graph

int V;

struct AdjList* array;

};

struct AdjListNode* newAdjListNode(

int dest, int weight)

struct AdjListNode* newNode =

(struct AdjListNode*)

malloc(sizeof(struct AdjListNode));

newNode->dest = dest;

newNode->weight = weight;

newNode->next = NULL;
return newNode;

struct Graph* createGraph(int V)

struct Graph* graph = (struct Graph*)

malloc(sizeof(struct Graph));

graph->V = V;

// Create an array of adjacency lists.

// Size of array will be V

graph->array = (struct AdjList*)

malloc(V * sizeof(struct AdjList));

// Initialize each adjacency list

// as empty by making head as NULL

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

graph->array[i].head = NULL;

return graph;

// Adds an edge to an undirected graph

void addEdge(struct Graph* graph, int src,

int dest, int weight)

// Add an edge from src to dest.

// A new node is added to the adjacency

// list of src. The node is

// added at the beginning

struct AdjListNode* newNode =


newAdjListNode(dest, weight);

newNode->next = graph->array[src].head;

graph->array[src].head = newNode;

// Since graph is undirected,

// add an edge from dest to src also

newNode = newAdjListNode(src, weight);

newNode->next = graph->array[dest].head;

graph->array[dest].head = newNode;

// Structure to represent a min heap node

struct MinHeapNode

int v;

int dist;

};

// Structure to represent a min heap

struct MinHeap

// Number of heap nodes present currently

int size;

// Capacity of min heap

int capacity;

// This is needed for decreaseKey()

int *pos;

struct MinHeapNode **array;


};

// A utility function to create a

// new Min Heap Node

struct MinHeapNode* newMinHeapNode(int v,

int dist)

struct MinHeapNode* minHeapNode =

(struct MinHeapNode*)

malloc(sizeof(struct MinHeapNode));

minHeapNode->v = v;

minHeapNode->dist = dist;

return minHeapNode;

// A utility function to create a Min Heap

struct MinHeap* createMinHeap(int capacity)

struct MinHeap* minHeap =

(struct MinHeap*)

malloc(sizeof(struct MinHeap));

minHeap->pos = (int *)malloc(

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)

struct MinHeapNode* t = *a;

*a = *b;

*b = t;

void minHeapify(struct MinHeap* minHeap,

int idx)

int smallest, left, right;

smallest = idx;

left = 2 * idx + 1;

right = 2 * idx + 2;

if (left < minHeap->size &&

minHeap->array[left]->dist <

minHeap->array[smallest]->dist )

smallest = left;

if (right < minHeap->size &&

minHeap->array[right]->dist <

minHeap->array[smallest]->dist )

smallest = right;

if (smallest != idx)

// The nodes to be swapped in min heap

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);

// A utility function to check if

// the given minHeap is empty or not

int isEmpty(struct MinHeap* minHeap)

return minHeap->size == 0;

// Standard function to extract

// minimum node from heap

struct MinHeapNode* extractMin(struct MinHeap*

minHeap)

if (isEmpty(minHeap))

return NULL;
// Store the root node

struct MinHeapNode* root =

minHeap->array[0];

// Replace root node with last node

struct MinHeapNode* lastNode =

minHeap->array[minHeap->size - 1];

minHeap->array[0] = lastNode;

// Update position of last node

minHeap->pos[root->v] = minHeap->size-1;

minHeap->pos[lastNode->v] = 0;

// Reduce heap size and heapify root

--minHeap->size;

minHeapify(minHeap, 0);

return root;

void decreaseKey(struct MinHeap* minHeap,

int v, int dist)

// Get the index of v in heap array

int i = minHeap->pos[v];

// Get the node and update its dist value

minHeap->array[i]->dist = dist;

while (i && minHeap->array[i]->dist <

minHeap->array[(i - 1) / 2]->dist)
{

// Swap this node with its parent

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]);

// move to parent index

i = (i - 1) / 2;

// A utility function to check if a given vertex

// 'v' is in min heap or not

bool isInMinHeap(struct MinHeap *minHeap, int v)

if (minHeap->pos[v] < minHeap->size)

return true;

return false;

// A utility function used to print the solution

void printArr(int dist[], int n)

printf("Vertex Distance from Source\n");

for (int i = 0; i < n; ++i)

printf("%d \t\t %d\n", i, dist[i]);

}
// The main function that calculates

// distances of shortest paths from src to all

// vertices. It is a O(ELogV) function

void dijkstra(struct Graph* graph, int src)

// Get the number of vertices in graph

int V = graph->V;

// dist values used to pick

// minimum weight edge in cut

int dist[V];

// minHeap represents set E

struct MinHeap* minHeap = createMinHeap(V);

// Initialize min heap with all

// vertices. dist value of all vertices

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

dist[v] = INT_MAX;

minHeap->array[v] = newMinHeapNode(v,

dist[v]);

minHeap->pos[v] = v;

// Make dist value of src vertex

// as 0 so that it is extracted first

minHeap->array[src] =

newMinHeapNode(src, dist[src]);

minHeap->pos[src] = src;
dist[src] = 0;

decreaseKey(minHeap, src, dist[src]);

// Initially size of min heap is equal to V

minHeap->size = V;

// In the following loop,

// min heap contains all nodes

// whose shortest distance

// is not yet finalized.

while (!isEmpty(minHeap))

// Extract the vertex with

// minimum distance value

struct MinHeapNode* minHeapNode =

extractMin(minHeap);

// Store the extracted vertex number

int u = minHeapNode->v;

// Traverse through all adjacent

// vertices of u (the extracted

// vertex) and update

// their distance values

struct AdjListNode* pCrawl =

graph->array[u].head;

while (pCrawl != NULL)

int v = pCrawl->dest;

// If shortest distance to v is
// not finalized yet, and distance to v

// through u is less than its

// previously calculated distance

if (isInMinHeap(minHeap, v) &&

dist[u] != INT_MAX &&

pCrawl->weight + dist[u] < dist[v])

dist[v] = dist[u] + pCrawl->weight;

// update distance

// value in min heap also

decreaseKey(minHeap, v, dist[v]);

pCrawl = pCrawl->next;

// print the calculated shortest distances

printArr(dist, V);

// Driver program to test above functions

int main()

// create the graph given in above figure

int V = 9;

struct Graph* graph = createGraph(V);

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;

void BellmanFord(int graph[][3], int V, int E,

int src)

int dis[V];

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

dis[i] = INT_MAX;

dis[src] = 0;

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

for (int j = 0; j < E; j++) {

if (dis[graph[j][0]] != INT_MAX && dis[graph[j][0]] + graph[j][2] <

dis[graph[j][1]])

dis[graph[j][1]] =

dis[graph[j][0]] + graph[j][2];

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

int x = graph[i][0];

int y = graph[i][1];

int weight = graph[i][2];


if (dis[x] != INT_MAX &&

dis[x] + weight < dis[y])

cout << "Graph contains negative"

" weight cycle"

<< endl;

cout << "Vertex Distance from Source" << endl;

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

cout << i << "\t\t" << dis[i] << endl;

int main()

int V = 5; // Number of vertices in graph

int E = 8; // Number of edges in graph

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)

Space complexity: O(V) [Linear space]

V being the number of vertices.

3) Connected components:

#include <bits/stdc++.h>

using namespace std;

class Graph {

int V; // No. of vertices

list<int>* adj;

// A function used by DFS

void DFSUtil(int v, bool visited[]);

public:
Graph(int V); // Constructor

~Graph();

void addEdge(int v, int w);

void connectedComponents();

};

void Graph::connectedComponents()

// Mark all the vertices as not visited

bool* visited = new bool[V];

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

visited[v] = false;

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

if (visited[v] == false) {

// print all reachable vertices

// from v

DFSUtil(v, visited);

cout << "\n";

}
delete[] visited;

void Graph::DFSUtil(int v, bool visited[])

// Mark the current node as visited and print it

visited[v] = true;

cout << v << " ";

// Recur for all the vertices

// adjacent to this vertex

list<int>::iterator i;

for (i = adj[v].begin(); i != adj[v].end(); ++i)

if (!visited[*i])

DFSUtil(*i, visited);

Graph::Graph(int V)

this->V = V;

adj = new list<int>[V];

}
Graph::~Graph() { delete[] adj; }

// method to add an undirected edge

void Graph::addEdge(int v, int w)

adj[v].push_back(w);

adj[w].push_back(v);

// Driver code

int main()

// Create a graph given in the above diagram

Graph g(5); // 5 vertices numbered from 0 to 4

g.addEdge(1, 0);

g.addEdge(2, 1);

g.addEdge(3, 4);

cout << "Following are connected components \n";

g.connectedComponents();
return 0;

4) Prim’s algorithm:

#include <limits.h>

#include <stdio.h>

#include <stdlib.h>

// A structure to represent a node in adjacency list

struct AdjListNode {

int dest;

int weight;

struct AdjListNode* next;

};

// A structure to represent an adjacency list

struct AdjList {

struct AdjListNode*

head; // pointer to head node of list


};

// A structure to represent a graph. A graph is an array of

// adjacency lists. Size of array will be V (number of

// vertices in graph)

struct Graph {

int V;

struct AdjList* array;

};

// A utility function to create a new adjacency list node

struct AdjListNode* newAdjListNode(int dest, int weight)

struct AdjListNode* newNode

= (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

struct Graph* createGraph(int V)

struct Graph* graph

= (struct Graph*)malloc(sizeof(struct Graph));

graph->V = V;

// Create an array of adjacency lists. Size of array

// will be V

graph->array = (struct AdjList*)malloc(

V * sizeof(struct AdjList));

// Initialize each adjacency list as empty by making

// head as NULL

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

graph->array[i].head = NULL;

return graph;

// Adds an edge to an undirected graph

void addEdge(struct Graph* graph, int src, int dest,


int weight)

// Add an edge from src to dest. A new node is added to

// the adjacency list of src. The node is added at the

// beginning

struct AdjListNode* newNode

= newAdjListNode(dest, weight);

newNode->next = graph->array[src].head;

graph->array[src].head = newNode;

// Since graph is undirected, add an edge from dest to

// src also

newNode = newAdjListNode(src, weight);

newNode->next = graph->array[dest].head;

graph->array[dest].head = newNode;

// Structure to represent a min heap node

struct MinHeapNode {

int v;

int key;

};
// Structure to represent a min heap

struct MinHeap {

int size; // Number of heap nodes present currently

int capacity; // Capacity of min heap

int* pos; // This is needed for decreaseKey()

struct MinHeapNode** array;

};

// A utility function to create a new Min Heap Node

struct MinHeapNode* newMinHeapNode(int v, int key)

struct MinHeapNode* minHeapNode

= (struct MinHeapNode*)malloc(

sizeof(struct MinHeapNode));

minHeapNode->v = v;

minHeapNode->key = key;

return minHeapNode;

// A utility function to create a Min Heap

struct MinHeap* createMinHeap(int capacity)


{

struct MinHeap* minHeap

= (struct MinHeap*)malloc(sizeof(struct MinHeap));

minHeap->pos = (int*)malloc(capacity * sizeof(int));

minHeap->size = 0;

minHeap->capacity = capacity;

minHeap->array = (struct MinHeapNode**)malloc(

capacity * sizeof(struct MinHeapNode*));

return minHeap;

// A utility function to swap two nodes of min heap. Needed

// for min heapify

void swapMinHeapNode(struct MinHeapNode** a,

struct MinHeapNode** b)

struct MinHeapNode* t = *a;

*a = *b;

*b = t;

// A standard function to heapify at given idx


// This function also updates position of nodes when they

// are swapped. Position is needed for decreaseKey()

void minHeapify(struct MinHeap* minHeap, int idx)

int smallest, left, right;

smallest = idx;

left = 2 * idx + 1;

right = 2 * idx + 2;

if (left < minHeap->size

&& minHeap->array[left]->key

< minHeap->array[smallest]->key)

smallest = left;

if (right < minHeap->size

&& minHeap->array[right]->key

< minHeap->array[smallest]->key)

smallest = right;

if (smallest != idx) {

// The nodes to be swapped in min heap

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);

// A utility function to check if the given minHeap is empty

// or not

int isEmpty(struct MinHeap* minHeap)

return minHeap->size == 0;

}
// Standard function to extract minimum node from heap

struct MinHeapNode* extractMin(struct MinHeap* minHeap)

if (isEmpty(minHeap))

return NULL;

// Store the root node

struct MinHeapNode* root = minHeap->array[0];

// Replace root node with last node

struct MinHeapNode* lastNode

= minHeap->array[minHeap->size - 1];

minHeap->array[0] = lastNode;

// Update position of last node

minHeap->pos[root->v] = minHeap->size - 1;

minHeap->pos[lastNode->v] = 0;

// Reduce heap size and heapify root

--minHeap->size;

minHeapify(minHeap, 0);
return root;

// Function to decrease key value of a given vertex v. This

// function uses pos[] of min heap to get the current index

// of node in min heap

void decreaseKey(struct MinHeap* minHeap, int v, int key)

// Get the index of v in heap array

int i = minHeap->pos[v];

// Get the node and update its key value

minHeap->array[i]->key = key;

// Travel up while the complete tree is not heapified.

// This is a O(Logn) loop

while (i

&& minHeap->array[i]->key

< minHeap->array[(i - 1) / 2]->key) {

// Swap this node with its parent

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]);

// move to parent index

i = (i - 1) / 2;

// A utility function to check if a given vertex

// 'v' is in min heap or not

bool isInMinHeap(struct MinHeap* minHeap, int v)

if (minHeap->pos[v] < minHeap->size)

return true;

return false;

// A utility function used to print the constructed MST

void printArr(int arr[], int n)

for (int i = 1; i < n; ++i)

printf("%d - %d\n", arr[i], i);


}

// The main function that constructs Minimum Spanning Tree

// (MST) using Prim's algorithm

void PrimMST(struct Graph* graph)

int V = graph->V; // Get the number of vertices in graph

int parent[V]; // Array to store constructed MST

int key[V]; // Key values used to pick minimum weight

// edge in cut

// minHeap represents set E

struct MinHeap* minHeap = createMinHeap(V);

// Initialize min heap with all vertices. Key value of

// all vertices (except 0th vertex) is initially

// infinite

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

parent[v] = -1;

key[v] = INT_MAX;

minHeap->array[v] = newMinHeapNode(v, key[v]);

minHeap->pos[v] = v;
}

// Make key value of 0th vertex as 0 so that it

// is extracted first

key[0] = 0;

minHeap->array[0] = newMinHeapNode(0, key[0]);

minHeap->pos[0] = 0;

// Initially size of min heap is equal to V

minHeap->size = V;

// In the following loop, min heap contains all nodes

// not yet added to MST.

while (!isEmpty(minHeap)) {

// Extract the vertex with minimum key value

struct MinHeapNode* minHeapNode

= extractMin(minHeap);

int u

= minHeapNode

->v; // Store the extracted vertex number

// Traverse through all adjacent vertices of u (the


// extracted vertex) and update their key values

struct AdjListNode* pCrawl = graph->array[u].head;

while (pCrawl != NULL) {

int v = pCrawl->dest;

// If v is not yet included in MST and weight of

// u-v is less than key value of v, then update

// key value and parent of v

if (isInMinHeap(minHeap, v)

&& pCrawl->weight < key[v]) {

key[v] = pCrawl->weight;

parent[v] = u;

decreaseKey(minHeap, v, key[v]);

pCrawl = pCrawl->next;

// print edges of MST

printArr(parent, V);

}
// Driver program to test above functions

int main()

// Let us create the graph given in above figure

int V = 9;

struct Graph* graph = createGraph(V);

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;

Time complexity of Prim's algorithm to be O( V(log(v)) + E(log(V)) ).

Prim's algorithm has a space complexity of O( E + V ).

5) Kruskal’s algorithm:

#include <bits/stdc++.h>

using namespace std;

#define V 5

int parent[V];

// Find set of vertex i

int find(int i)

while (parent[i] != i)

i = parent[i];

return i;
}

void union1(int i, int j)

int a = find(i);

int b = find(j);

parent[a] = b;

// Finds MST using Kruskal's algorithm

void kruskalMST(int cost[][V])

int mincost = 0; // Cost of min MST.

// Initialize sets of disjoint sets.

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

parent[i] = i;

// Include minimum weight edges one by one

int edge_count = 0;

while (edge_count < V - 1) {

int min = INT_MAX, a = -1, b = -1;


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

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

if (find(i) != find(j) && cost[i][j] < min) {

min = cost[i][j];

a = i;

b = j;

union1(a, b);

printf("Edge %d:(%d, %d) cost:%d \n",

edge_count++, a, b, min);

mincost += min;

printf("\n Minimum cost= %d \n", mincost);

// driver program to test above function

int main()

{
int cost[][V] = {

{ INT_MAX, 2, INT_MAX, 6, INT_MAX },

{ 2, INT_MAX, 3, 8, 5 },

{ INT_MAX, 3, INT_MAX, INT_MAX, 7 },

{ 6, 8, INT_MAX, INT_MAX, 9 },

{ INT_MAX, 5, 7, 9, INT_MAX },

};

// Print the solution

kruskalMST(cost);

return 0;

A worst-case time complexity of O(E(log(E)).

An average-case time complexity of O(E(log(E)).

A best-case time complexity of O(E(log(E)).

A space complexity of O(E+V).

You might also like