#include <iostream>
#include <vector>
#include <list>
#include <unordered_map>
#include <climits>
#include <algorithm>
using namespace std;
bool compa(vector<int>& a, vector<int>& b) {
return a[2] < b[2];
}
void MakeSet(vector<int>& parent, vector<int>& rank, int n) {
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 0;
}
}
int FindParent(vector<int>& parent, int node) {
if (parent[node] == node) {
return node;
}
return parent[node] = FindParent(parent, parent[node]);
}
void UnionSet(int u, int v, vector<int>& parent, vector<int>& rank) {
u = FindParent(parent, u);
v = FindParent(parent, v);
if (rank[u] < rank[v]) {
parent[u] = v;
} else if (rank[u] > rank[v]) {
parent[v] = u;
} else {
parent[v] = u;
rank[u]++;
}
}
int KruskalsMST(vector<vector<int>>& edge, int n) {
sort(edge.begin(), edge.end(), compa);
vector<int> parent(n);
vector<int> rank(n);
MakeSet(parent, rank, n);
int MinWgt = 0;
for (int i = 0; i < edge.size(); i++) {
int u = edge[i][0];
int v = edge[i][1];
int weight = edge[i][2];
int parent_u = FindParent(parent, u);
int parent_v = FindParent(parent, v);
if (parent_u != parent_v) {
MinWgt += weight;
UnionSet(parent_u, parent_v, parent, rank);
}
}
return MinWgt;
}
vector<pair<pair<int, int>, int>> PrimsMST(int n, vector<pair<pair<int, int>,
int>>& g) {
unordered_map<int, list<pair<int, int>>> adj;
for (int i = 0; i < g.size(); i++) {
int u = g[i].first.first;
int v = g[i].first.second;
int w = g[i].second;
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w));
}
vector<int> key(n + 1, INT_MAX);
vector<bool> mst(n + 1, false);
vector<int> parent(n + 1, -1);
key[1] = 0;
for (int i = 1; i < n; i++) {
int mini = INT_MAX;
int u;
for (int v = 1; v <= n; v++) {
if (!mst[v] && key[v] < mini) {
u = v;
mini = key[v];
}
}
mst[u] = true;
for (auto it : adj[u]) {
int v = it.first;
int w = it.second;
if (!mst[v] && w < key[v]) {
parent[v] = u;
key[v] = w;
}
}
}
vector<pair<pair<int, int>, int>> result;
for (int i = 2; i <= n; i++) {
result.push_back(make_pair(make_pair(parent[i], i), key[i]));
}
return result;
}
int main() {
int choice;
cout << "Select the algorithm to find MST:\n";
cout << "1. Kruskal's Algorithm\n";
cout << "2. Prim's Algorithm\n";
cout << "Enter choice (1 or 2): ";
cin >> choice;
if (choice == 1) {
vector<vector<int>> edges = {
{0, 1, 10},
{0, 2, 6},
{0, 3, 5},
{1, 3, 15},
{2, 3, 4}
};
int n = 4;
cout << "Minimum Spanning Tree Weight (Kruskal's): " << KruskalsMST(edges,
n) << endl;
}
else if (choice == 2) {
int n = 5;
vector<pair<pair<int, int>, int>> graph = {
{{1, 2}, 2}, {{1, 3}, 3}, {{2, 3}, 1}, {{2, 4}, 4}, {{3, 4}, 5}, {{3,
5}, 6}, {{4, 5}, 7}
};
vector<pair<pair<int, int>, int>> mst = PrimsMST(n, graph);
cout << "Edges in the MST (Prim's):\n";
for (auto edge : mst) {
cout << edge.first.first << " - " << edge.first.second << " : " <<
edge.second << "\n";
}
}
else {
cout << "Invalid choice. Please select either 1 or 2." << endl;
}
return 0;
}