-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path08 Kruskal's MST.cpp
149 lines (108 loc) · 2.6 KB
/
08 Kruskal's MST.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
Complexity : O(ElogE)
Works fine with negative edges.
**/
/**Which of the favors of your Lord will you deny ?**/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define MP make_pair
#define F first
#define S second
#define INF INT_MAX
#define ALL(x) (x).begin(), (x).end()
#define DBG(x) cerr << __LINE__ << " says: " << #x << " = " << (x) << endl
inline void optimizeIO()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}
const int nmax = 1e3+7;
const LL LINF = 1e17;
struct Edge {
int src, dest, weight;
};
// Comparison object to be used to order the Edges
struct compare1
{
inline bool operator() (Edge const &a, Edge const &b)
{
return (a.weight > b.weight);
}
};
struct compare2
{
inline bool operator() (Edge const &a, Edge const &b)
{
return (a.weight < b.weight);
}
};
class DisjointSet
{
unordered_map<int, int> parent;
public:
void makeSet(int N)
{
for (int i = 1; i <= N; i++) /** 1 based indexing **/
parent[i] = i;
}
int Find(int k)
{
// if k is root
if (parent[k] == k)
return k;
return parent[k] = Find(parent[k]);
}
void Union(int a, int b)
{
int x = Find(a);
int y = Find(b);
parent[x] = y;
}
};
vector<Edge> KruskalAlgoMinST(vector<Edge> edges, int N)
{
sort(edges.begin(), edges.end(), compare1()); /** Sorted in the opposite way because of POP_BACK implementation , use compare2 for Maximum Spanning Tree **/
vector<Edge> MST;
DisjointSet ds;
ds.makeSet(N);
/** MST contains exactly V-1 edges **/
while (MST.size() != N - 1)
{
/** consider next edge with minimum weight from the graph **/
Edge next_edge = edges.back();
edges.pop_back();
/** find root of the sets to which two endpoint vertices of next_edge belongs **/
int x = ds.Find(next_edge.src);
int y = ds.Find(next_edge.dest);
/** if both endpoints have different parents, they belong to different connected components and can be included in MST **/
if (x != y)
{
MST.push_back(next_edge);
ds.Union(x, y);
}
}
return MST;
}
int nodes,num_edges;
vector<Edge>adj;
int main()
{
//freopen("out.txt","w",stdout);
optimizeIO();
cin>>nodes>>num_edges;
for(int i=1;i<=num_edges;i++)
{
int a,b,w;
cin>>a>>b>>w;
adj.push_back({a,b,w}); /** although undirected , edge is pushed once to avoid cycle of x->y & y->x **/
}
vector<Edge>MinST = KruskalAlgoMinST(adj,nodes);
LL mininum_spanning_tree_value = 0;
for(auto e:MinST)
mininum_spanning_tree_value += e.weight;
cout<<mininum_spanning_tree_value<<endl;
return 0;
}