forked from HarshCasper/NeoAlgo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
minimum_spanning_tree.cpp
129 lines (118 loc) · 2.92 KB
/
minimum_spanning_tree.cpp
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
/*
There are n vertices and e edges and their weights,
you need to construct minimum spanning tree.
vertex numbers start from 0.
Input:
first line containes the value of n and e.
next e lines follow 3 space seperated integers u, v, w, which means
there is a path between u and v having weight w.
Output:
First line containing the minimum weight of the tree.
next n-1 lines containes 2 space seperated integer u, v & w.
i.e. u and v have a path between them in the formed MST.
and w denotes the weight.
Efficiency: O(e log e + e alpha e)
Language: C++17
*/
#include <bits/stdc++.h>
using namespace std;
#define MAX_VERTICES 100005
vector <int> parent(MAX_VERTICES);
vector <int> max_depth(MAX_VERTICES);
//optimised find function
int findparent(int u)
{
while (u != parent[u])
{
//path compression technique
parent[u] = parent[parent[u]];
u = parent[u];
}
return u;
}
//union function
void take_union(int u, int v)
{
u = findparent(u);
v = findparent(v);
if (max_depth[u] > max_depth[v])
parent[v] = parent[u];
else if (max_depth[u] < max_depth[v])
parent[u] = parent[v];
else
{
max_depth[u]++;
parent[v] = u;
}
}
int main()
{
//decale and read the values of number of
//vertices and edges respectively
int n, e;
cin >> n >> e;
//declare and read the values of edge list
//edge_list.first contains the weight
//edge_list.second.first contains the value of u
//edge_list.second.second contains the value of v.
vector <pair <int, pair<int, int> > > edges_list(e);
for (int i = 0; i < e; i++)
{
cin >> edges_list[i].second.first >> edges_list[i].second.second;
cin >> edges_list[i].first;
}
//sort the vector in ascending order in order to keep
//the edge with weight less first.
sort(edges_list.begin(), edges_list.end());
//initialize the parent and max_depth vector.
for (int i = 0; i <= n; i++)
parent[i] = i, max_depth[i] = 0;
//check one-by-one whether to add the edge to mst or not.
int count_of_edge_mst = 0, total_weight = 0;
vector <pair <int, pair<int, int> > > final_edge_mst;
for (int i = 0; i < e and count_of_edge_mst < n - 1; i++)
{
//check whether or not to add this edge
if (findparent(edges_list[i].second.first) != findparent(edges_list[i].second.second))
{
take_union(edges_list[i].second.first, edges_list[i].second.second);
//add the dge into the final edge vector
final_edge_mst.push_back(edges_list[i]);
//increment the total weight
total_weight += edges_list[i].first;
count_of_edge_mst++;
}
}
cout << total_weight << endl;
for (auto val : final_edge_mst)
cout << val.second.first << " " << val.second.second << " " << val.first << endl;
return 0;
}
/*
Sample Input 1:
9 14
0 1 4
0 7 8
1 7 11
1 2 8
7 6 1
7 8 7
6 5 2
8 6 6
2 8 2
2 3 7
2 5 4
3 5 14
2 4 9
5 4 10
Sample Output:
37
7 6 1
2 8 2
6 5 2
0 1 4
2 5 4
2 3 7
0 7 8
2 4 9
*/