You are on page 1of 10

AMBO UNIVERSITY

HACHALU HUNDESSA CAMPUS


DEPARTMENT OF COMPUTER SCIENCE
DESIGN AND ANALYSIS OF ALGORITHMS ASSIGNMENT
SECTION:- 1

NAME ID NO

NABIL MOHAMMED………………………..UGR/51354/13

SUBMITTED TO: MR ABEBE. Z


SUBMISSION DATE: 6/11/2023
AMBO, ETHIOPIA
The implementation of Prim's algorithm
Prim's algorithm is a greedy algorithm used to find the minimum spanning tree (MST) of a given
weighted, connected, and undirected graph. The MST is a tree that connects all the vertices in
the graph, while minimizing the sum of the edge weights.
Here's the implementation of prism's algorithm in iterative form in C++:

c++
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100001
#define INF 1000000000

int n, m;
vector<pair<int, int>> adj[MAXN];
bool visited[MAXN];
int dist[MAXN];

int prim() {
// Initialize the distances to infinity and visited to false
for (int i = 1; i <= n; i++) {
dist[i] = INF;
visited[i] = false;
}
// Initialize the priority queue with the source vertex
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push(make_pair(0, 1)); // (distance, vertex)
dist[1] = 0;
int ans = 0;
// Iterate until the priority queue is empty
while (!pq.empty()) {
// Pop the vertex with the smallest distance from the priority queue
int u = pq.top().second;
pq.pop();
// Skip if vertex is already visited
if (visited[u]) continue;
visited[u] = true;
ans += dist[u];
// Iterate through all adjacent vertices
for (auto v : adj[u]) {
// If the vertex is not visited and the edge has smaller weight, update the
distance and add to the priority queue
if (!visited[v.first] && dist[v.first] > v.second) {
dist[v.first] = v.second;
pq.push(make_pair(dist[v.first], v.first));
}
}
}
return ans;
}
int main() {
cin >> n >> m; // Number of vertices, number of edges
// Read in the graph
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w));
}
// Call the Prim's algorithm function and output the result
cout << prim() << "\n";
return 0;
}

The time complexity of Prism's algorithm is O(E log V) using the priority queue.

The implementation of Kruskal's algorithm

Kruskal's algorithm is another greedy algorithm that finds a minimum spanning tree for a
weighted undirected graph. The algorithm operates by sorting all the edges in increasing order
of their weight, and then adding them to the MST one at a time, as long as they do not create a
cycle.
Here's the implementation of Kruskal's algorithm in iterative form in C++:

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

# define INF 0x3f3f3f3f


typedef pair<int, int> iPair;
class Graph
{
int V, E;
vector< pair<int, iPair> > edges;
public:
Graph(int V, int E);
void addEdge(int u, int v, int w);
int kruskalMST();
};
Graph::Graph(int V, int E)
{
this->V = V;
this->E = E;
}
void Graph::addEdge(int u, int v, int w)
{
edges.push_back({w, {u, v}});
}
int Graph::kruskalMST()
{
int mst_wt = 0;
sort(edges.begin(), edges.end());

vector<int> parent(V);
for (int i = 0; i < V; i++)
parent[i] = i;

int cnt = 0;
for (auto it : edges)
{
int u = it.second.first;
int v = it.second.second;
int set_u = parent[u];
int set_v = parent[v];

if (set_u != set_v)
{
cout << u << " - " << v << endl;
mst_wt += it.first;
cnt++;

for(int i=0;i<V;i++)
{
if(parent[i]==set_v)
{
parent[i]=set_u;
}
}
}
if(cnt==V-1)
break;
}

return mst_wt;
}
int main()
{
int V = 5, E = 7;
Graph g(V, E);

g.addEdge(0, 1, 2);
g.addEdge(0, 3, 6);
g.addEdge(1, 2, 3);
g.addEdge(1, 3, 8);
g.addEdge(1, 4, 5);
g.addEdge(2, 4, 7);
g.addEdge(3, 4, 9);

cout << "Edges of MST are \n";


int mst_wt = g.kruskalMST();

cout << "\nWeight of MST is " << mst_wt;

return 0;
}

The time complexity of this algorithm can be O(ElogE) or O(ElogV), depending on how we
implement the sorting of edges.
The total time complexity of Kruskal's algorithm is O(ElogE + ElogV) or O(ElogE + E) depending
on the implementation of sorting.
//ElogE for sorting E edges in edge_list
//ElogV for applying FIND & UNION operations on E edges having V vertices
The implementation of Dijkstra's algorithm
Dijkstra's algorithm is another popular graph algorithm used to find the shortest path from a
single source vertex to all other vertices in a graph with non-negative edge weights. The
algorithm operates by maintaining a set of visited vertices and distances from the source vertex
to all other vertices. At each iteration, it selects the vertex with the smallest distance from the
source vertex that has not been visited, updates the distances of its neighbors if a shorter path
can be found, and adds it to the set of visited vertices.

Here's the implementation of Dijkstra's algorithm in iterative form in C++:

c++
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100001
#define INF 1000000000

int n, m;
vector<pair<int, int>> adj[MAXN];
int dist[MAXN];
bool visited[MAXN];

int dijkstra(int s) {
// Initialize distances to infinity and visited to false
for (int i = 1; i <= n; i++) {
dist[i] = INF;
visited[i] = false;
}
// Initialize the priority queue with the source vertex
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push(make_pair(0, s)); // (distance, vertex)
dist[s] = 0;
// Iterate until the priority queue is empty
while (!pq.empty()) {
// Pop the vertex with the smallest distance from the priority queue
int u = pq.top().second;
pq.pop();
// Skip if vertex is already visited
if (visited[u]) continue;
visited[u] = true;
// Iterate through all adjacent vertices
for (auto v : adj[u]) {
// If the vertex is not visited and the distance can be updated, update the
distance and add to the priority queue
if (!visited[v.first] && dist[v.first] > dist[u] + v.second) {
dist[v.first] = dist[u] + v.second;
pq.push(make_pair(dist[v.first], v.first));
}
}
}
return dist[n];
}
int main() {
cin >> n >> m; // Number of vertices, number of edges
// Read in the graph as an adjacency list with weights
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w)); // Add both directions for an undirected
graph
}
// Call the Dijkstra's algorithm function with source vertex 1 and output the result
cout << dijkstra(1) << "\n";
return 0;
}

The time complexity of Dijkstra's algorithm is O(VlogV + ElogV) or simply O((V + E)logV), where
E is the number of edges in the graph.
However, if we use an adjacency list to represent the graph and a binary heap to implement the
priority queue, then the time complexity of Dijkstra's algorithm becomes O((V+E)logV), which is
faster than that of using a Fibonacci heap.

You might also like