Kruskal
Introduction:
This algorithm finds an MST(minimum spanning tree) from a connected undirected graph. Remember that this algorithm fails sometimes in case of directed graph since kruskal's algorithm finds a cylce when there is none.
Problem Statement:
Find minimum spanning tree of an undirected graph G.
Algorithm
Code :
#include <bits/stdc++.h> using namespace std; #define adjacency_list map<int, vector<pair<int, int>>> #define mp make_pair #define INF INT_MAX typedef struct edge { int u; int v; int w; } Edge; typedef struct graph { adjacency_list adj; int num_edges; int num_vertices; Edge *edge; } graph; int edge_compare(const void *a, const void *b) { Edge *c = (Edge *)a; Edge *d = (Edge *)b; return c->w > d->w; // return 1 i.e., swap if greater } int find_parent(map<int, int> &parent, int u) { if (parent[u] != u) { parent[u] = find_parent(parent, parent[u]); } return parent[u]; } void Union(map<int, int> &rank, map<int, int> &parent, int rootu, int rootv) { if (rank[rootu] < rank[rootv]) { parent[rootu] = rootv; } else if (rank[rootv] < rank[rootu]) { parent[rootv] = rootu; } else { parent[rootv] = rootu; rank[rootu]++; } } void kruskal(graph G) { qsort(G.edge, G.num_edges, sizeof(Edge), edge_compare); // cout<<"kruskal-"<<G.num_edges<<"\n"; map<int, int> parent; map<int, int> rank; for (int i = 0; i < G.num_vertices; i++) { parent[i] = i; // rank[i] = 0; // not needed since we are using map } int sum = 0, cnt = 0, i = 0; for (int i = 0; i < G.num_edges; i++) { int rootu = find_parent(parent, G.edge[i].u); int rootv = find_parent(parent, G.edge[i].v); if (rootu != rootv) { Union(rank, parent, rootu, rootv); cnt++; // this edge is part of MST sum += G.edge[i].w; cout << G.edge[i].u << " " << G.edge[i].v << " " << G.edge[i].w << "\n"; if (cnt >= G.num_vertices - 1) { break; } } } cout << sum << "\n"; } int main() { // undirected graph graph G; // u - {{v1,w1}, {v2, w2}, .... {vk,wk}} cin >> G.num_vertices; cin >> G.num_edges; G.edge = new Edge[G.num_edges]; int u, v, w; for (int i = 0; i < G.num_edges; i++) { cin >> G.edge[i].u >> G.edge[i].v >> G.edge[i].w; } kruskal(G); // cout << "\n"; }
Complexity Analysis :
Time complexity : \(O(|E|log|E|+|E|log|V|)\) where \(|E|log|E|\) is for sorting and \(log|V|\) is for Union-find algorithm.
Time complexity ≈ \(O(|E|log|V|)\) or \(O(|E|log|E|)\) since \(|E|\) ≤ \(|V|^2\)