2421.cpp (1550B)
1 class UnionFind { 2 int n, cnt = n; 3 vector<int> root, size; 4 5 public: 6 UnionFind(int n) : n(n), root(n), size(n, 1) { iota(root.begin(), root.end(), 0); } 7 8 int find(int x) { 9 while (x != root[x]) 10 x = root[x] = root[root[x]]; 11 return x; 12 } 13 14 void join(int x, int y) { 15 x = find(x), y = find(y); 16 if (x != y) { 17 if (size[x] > size[y]) swap(x, y); 18 root[x] = y; 19 size[y] += size[x]; 20 cnt--; 21 } 22 } 23 }; 24 25 class Solution { 26 public: 27 int numberOfGoodPaths(vector<int> &vals, vector<vector<int>> &edges) { 28 int n = vals.size(); 29 map<int, vector<int>> valuesToNodes; 30 vector<vector<int>> adj(n); 31 UnionFind uf(n); 32 33 for (auto &edge : edges) { 34 adj[edge[0]].push_back(edge[1]); 35 adj[edge[1]].push_back(edge[0]); 36 } 37 38 for (int i = 0; i < n; i++) 39 valuesToNodes[vals[i]].push_back(i); 40 41 int goodPaths = 0; 42 for (auto &[value, nodes] : valuesToNodes) { 43 for (int node : nodes) { 44 for (int neighbor : adj[node]) { 45 if (vals[node] >= vals[neighbor]) { 46 uf.join(node, neighbor); 47 } 48 } 49 } 50 unordered_map<int, int> group; 51 for (int u : nodes) 52 group[uf.find(u)]++; 53 for (auto &[_, size] : group) 54 goodPaths += (size * (size + 1) / 2); 55 } 56 return goodPaths; 57 } 58 };