-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathminimumSpanningTree.cpp
More file actions
153 lines (139 loc) · 4.08 KB
/
Copy pathminimumSpanningTree.cpp
File metadata and controls
153 lines (139 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <bits/stdc++.h>
using namespace std;
// TC -> O(N^2)
// SC -> O(2N)
vector<int> prims_brute(vector<pair<int, int>> adj[], int V)
{
// key :- Index of minimum edge for given node (node represent by index)
// mst :- Nodes that are already connected to spanning tree (node represent by index)
vector<int> parent(V, -1), key(V, INT_MAX);
vector<bool> mst(V, false);
key[0] = 0;
parent[0] = -1;
for (int count = 0; count < V - 1; ++count)
{
int minimumKey = INT_MAX, u = -1;
for (int i = 0; i < V; ++i)
{
if (key[i] < minimumKey && !mst[i])
minimumKey = key[i], u = i;
}
mst[u] = true;
for (const auto &it : adj[u])
{
int neighbor = it.first;
int weight = it.second;
if (!mst[neighbor] && key[neighbor] > weight)
key[neighbor] = weight, parent[neighbor] = u;
}
}
return parent;
}
// TC -> O(N+E) + O(NlogN)
// SC -> O(2N + 2N)
vector<int> prims_optimize(vector<pair<int, int>> adj[], int V)
{
// key :- Index of minimum edge for given node (node represent by index)
// mst :- Nodes that are already connected to spanning tree (node represent by index)
vector<int> parent(V, -1), key(V, INT_MAX);
vector<bool> mst(V, false);
// Min heap : (weight, vertex)
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
key[0] = 0;
parent[0] = -1;
pq.push({0, 0});
for (int count = 0; count < V - 1; ++count)
{
int u = pq.top().second;
pq.pop();
mst[u] = true;
for (auto it : adj[u])
{
int neighbor = it.first;
int weight = it.second;
if (!mst[neighbor] && key[neighbor] > weight)
{
pq.push({weight, neighbor});
key[neighbor] = weight, parent[neighbor] = u;
}
}
}
return parent;
}
class Disjoint_set
{
int *parent, *rank;
public:
Disjoint_set(int n)
{
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = i;
rank[i] = 0;
}
}
int findParent(int i)
{
if (parent[i] == i)
return i;
// return findParent(parent[i]); it will also work but we have to find root everytime so we use
// Path compression step
return parent[i] = findParent(parent[i]);
}
void unnion(int comp1, int comp2)
{
int par1 = findParent(comp1), par2 = findParent(comp2);
if(par1 == par2) return ;
// rank is required to maintain the depth of the tree
// since we only make parent those nodes who have higher rank
// and if rank is same then we have to increase the rank.
if (rank[par1] < rank[par2])
parent[par1] = par2;
else if (rank[par1] > rank[par2])
parent[par2] = par1;
else
parent[par1] = par2, ++rank[par2];
}
};
vector<pair<int, int>> kruskals(vector<vector<int>> &edges, int V)
{
// Sort all edges (weight u v)
sort(edges.begin(), edges.end());
Disjoint_set vertex(V);
// int cost = 0;
vector<pair<int, int>> mst;
for (auto it : edges)
{
if (vertex.findParent(it[1]) != vertex.findParent(it[2]))
{
// cost += it[0];
mst.push_back({it[1], it[2]});
vertex.unnion(it[1], it[2]);
}
}
return mst;
}
int main()
{
int V, E;
cout << "Enter number of vertices and edges: " << endl;
cin >> V >> E;
vector<pair<int, int>> adj[V];
vector<vector<int>> edges(E);
cout << "please enter as: vertex vertex weight :\n";
for (int i = 0; i < E; i++)
{
int u, v, w;
cin >> u >> v >> w;
edges.push_back({w, u, v});
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
vector<int> ans = prims_brute(adj, V);
vector<pair<int, int>> res = kruskals(edges, V);
for (auto it : res)
cout << it.first << "--" << it.second << endl;
return 0;
}