<style> html, body, .ui-content { background: #222222; color: #00BFFF; } /* 設定 code 模板 */ .markdown-body code, .markdown-body tt { background-color: #ffffff36; } .markdown-body .highlight pre, .markdown-body pre { color: #ddd; background-color: #00000036; } .hljs-tag { color: #ddd; } .token.operator { background-color: transparent; } </style> ###### tags: `Leetcode` # 2421. Number of Good Paths ###### Link : https://leetcode.com/problems/number-of-good-paths/description/ ## 題目 找到Good Path的數量 Good Path:起點和終點為相同數值且路徑中的數值小於等於起點或終點 ## 程式碼 <a href="https://hackmd.io/s9CujEpmTpW0LNmoqL_klw"> Disjiont Set-Union find(DSU) </a> ```cpp= class DSU{ public: DSU(int n) : parent(n){ for(int i=0; i < n; i++){ parent[i] = i; } } int findParent(int x){ if(parent[x] == x) return x; return parent[x] = findParent(parent[x]); } void UNION(int x, int y){ int parentx = findParent(x), parenty = findParent(y); if(parentx == parenty) return; parent[parenty] = parent[parentx]; return; } vector<int> parent; }; class Solution { public: int numberOfGoodPaths(vector<int>& vals, vector<vector<int>>& edges) { int n = vals.size(), ans=0; vector<vector<int>> adj(n); for(auto &edge : edges){//adj list adj[edge[0]].push_back(edge[1]); adj[edge[1]].push_back(edge[0]); } DSU dsu(n); map<int, vector<int>> valToNode;//<數值,對應到是這個數值的點> for(int i=0; i<n; i++){ valToNode[vals[i]].push_back(i); } for(auto [value, nodes] : valToNode){ for(auto &node : nodes){ for(auto &neighbor : adj[node]){ if(vals[neighbor] <= vals[node])//如果這個點的鄰居的數值小於這個點 dsu.UNION(node, neighbor);//將兩個點連接 } } unordered_map<int, int> freqOfRoot;//計算加入的點有多少是在同一棵樹中 for(auto &node : nodes){ freqOfRoot[dsu.findParent(node)]++; } for(auto it : freqOfRoot){ ans += it.second * (it.second + 1) / 2;//路徑數量等於每棵分開的樹所新增的點數量*(新增的點數量+1)/2 } } return ans; } }; ``` 今天一整天都在搞這個 我好快樂喔