forked from AnasImloul/Leetcode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFind Critical and Pseudo-Critical Edges in Minimum Spanning Tree.cpp
125 lines (103 loc) · 2.66 KB
/
Find Critical and Pseudo-Critical Edges in 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
class UnionFind{
private:
vector<int> parent_;
vector<int> rank_;
int sets_;
public:
UnionFind(int n)
{
init(n);
}
void init(int n)
{
sets_ = n;
parent_.resize(n);
rank_.resize(n);
iota(parent_.begin(),parent_.end(),0);
fill(rank_.begin(),rank_.end(),1);
}
int find(int u)
{
return parent_[u] == u ? u: parent_[u] = find(parent_[u]);
}
bool join(int u,int v)
{
u = find(u);
v = find(v);
if(u==v)
{
return false;
}
if(rank_[u]<rank_[v])
{
swap(u,v);
}
rank_[u] += rank_[v];
parent_[v] = u;
sets_ --;
return true;
}
bool united()
{
return sets_ == 1;
}
};
class Solution {
public:
vector<int> edges_idx_;
int kruskal(const int n, const int removed_edge_idx,const int init_edge_idx,
const vector<vector<int>> &edges)
{
UnionFind graph(n);
int edges_size = edges.size();
int total = 0;
if(init_edge_idx != -1)
{
graph.join(edges[init_edge_idx][0],edges[init_edge_idx][1]);
total += edges[init_edge_idx][2];
}
for(int i = 0; i<edges_size; ++i)
{
int edge_idx = edges_idx_[i];
if(edge_idx == removed_edge_idx)
{
continue;
}
int u = edges[edge_idx][0];
int v = edges[edge_idx][1];
if(graph.join(u,v))
{
total+= edges[edge_idx][2];
}
}
return graph.united() ? total : INT_MAX;
}
vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {
int edges_size = edges.size();
edges_idx_.resize(edges_size);
iota(edges_idx_.begin(),edges_idx_.end(),0);
sort(edges_idx_.begin(),edges_idx_.end(),[&edges](int a, int b){
return edges[a][2] < edges[b][2];
});
int mst = kruskal(n,-1,-1,edges);
vector<int> critical;
vector<int> psudo;
for(int i = 0; i< edges_size; ++i)
{
int edge_idx = edges_idx_[i];
int total = kruskal(n,-1,edge_idx,edges);
if(total == mst)
{
total = kruskal(n,edge_idx,-1,edges);
if(total > mst)
{
critical.push_back(edge_idx);
}
else{
psudo.push_back(edge_idx);
}
}
}
return {critical,psudo};
}
};