| 12
 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
 
 | class UF {public:
 vector<int> f;
 vector<int> size;
 int n;
 int setCount;
 UF(int _n): n(_n), setCount(_n), f(_n), size(_n, 1) {
 iota(f.begin(), f.end(), 0);
 }
 int find(int x) {
 return f[x] == x ? x : f[x] = find(f[x]);
 }
 bool _union(int x, int y) {
 x = find(x);
 y = find(y);
 if (x == y)
 return false;
 if (size[x] < size[y]) {
 swap(x, y);
 }
 f[y] = x;
 size[x] += size[y];
 --setCount;
 return true;
 }
 bool connected(int x, int y) {
 x = find(x);
 y = find(y);
 return x == y;
 }
 };
 class Solution {
 public:
 vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {
 const int m = edges.size();
 for (int i = 0; i < m; ++i)
 edges[i].push_back(i);
 sort(edges.begin(), edges.end(), [](const auto& u, const auto& v) {
 return u[2] < v[2];
 });
 UF uf_std(n);
 int value = 0;
 for (int i = 0; i < m; ++i)
 if (uf_std._union(edges[i][0], edges[i][1]))
 value += edges[i][2];
 vector<vector<int>> ans(2);
 for (int i = 0; i < m; ++i) {
 UF uf(n);
 int v = 0;
 for (int j = 0; j < m; ++j)
 if (i != j && uf._union(edges[j][0], edges[j][1]))
 v += edges[j][2];
 if (uf.setCount != 1
 || (uf.setCount == 1 && v > value)) {
 ans[0].push_back(edges[i][3]);
 continue;
 }
 uf = UF(n);
 uf._union(edges[i][0], edges[i][1]);
 v = edges[i][2];
 for (int j = 0; j < m; ++j)
 if (i != j && uf._union(edges[j][0], edges[j][1]))
 v += edges[j][2];
 if (v == value)
 ans[1].push_back(edges[i][3]);
 }
 return ans;
 }
 };
 
 |