并查集
- 一开始每个元素都以自己为一个集合
- find(i):查找 i 所在集合的代表元素,代表元素代表了 i 所在的集合
- isSameSet(a, b):判断 a、b 是否在同一个集合里
- union(a, b):将 a、b 所在的两个集合合并
| #include <iostream> |
| #include <vector> |
| #include <stack> |
| |
| using namespace std; |
| |
| int len; |
| |
| vector<int> father; |
| |
| vector<int> s1ze; |
| |
| stack<int> stk; |
| |
| void build() { |
| father.resize(len); |
| s1ze.resize(len); |
| for (int i = 0; i < len; ++i) { |
| |
| father[i] = i; |
| s1ze[i] = 1; |
| } |
| } |
| |
| int find(int x) { |
| while (x != father[x]) { |
| |
| stk.emplace(x); |
| x = father[x]; |
| } |
| |
| while (!empty(stk)) { |
| father[stk.top()] = x; |
| stk.pop(); |
| } |
| return x; |
| } |
| |
| bool isSameSet(int a, int b) { |
| return find(a) == find(b); |
| } |
| |
| void un1on(int a, int b) { |
| |
| int fatherOfA = find(a); |
| int fatherOfB = find(b); |
| |
| if (fatherOfA == fatherOfB) return; |
| |
| if (s1ze[fatherOfA] > s1ze[fatherOfB]) { |
| father[fatherOfB] = fatherOfA; |
| s1ze[fatherOfA] += s1ze[fatherOfB]; |
| } else { |
| father[fatherOfA] = fatherOfB; |
| s1ze[fatherOfB] += s1ze[fatherOfA]; |
| } |
| } |
| |
| int main() { |
| int N, M; |
| cin >> N >> M; |
| len = N + 1; |
| |
| build(); |
| |
| for (int i = 0, opt, a, b; i < M; ++i) { |
| cin >> opt >> a >> b; |
| if (opt == 1) { |
| if (isSameSet(a, b)) { |
| cout << "Yes" << endl; |
| } else { |
| cout << "No" << endl; |
| } |
| } else { |
| un1on(a, b); |
| } |
| } |
| } |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| int len; |
| |
| vector<int> father; |
| |
| void build() { |
| father.resize(len); |
| |
| for (int i = 0; i < len; ++i) |
| father[i] = i; |
| } |
| |
| int find(int x) { |
| |
| if (x != father[x]) |
| father[x] = find(father[x]); |
| return father[x]; |
| } |
| |
| bool isSameSet(int a, int b) { |
| return find(a) == find(b); |
| } |
| |
| void un1on(int a, int b) { |
| |
| father[find(a)] = find(b); |
| } |
| |
| int main() { |
| int N, M; |
| cin >> N >> M; |
| len = N + 1; |
| |
| build(); |
| |
| for (int i = 0, opt, a, b; i < M; ++i) { |
| cin >> opt >> a >> b; |
| if (opt == 2) { |
| if (isSameSet(a, b)) { |
| cout << "Y" << endl; |
| } else { |
| cout << "N" << endl; |
| } |
| } else { |
| un1on(a, b); |
| } |
| } |
| } |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| vector<int> father; |
| |
| int sets; |
| |
| void build(int len) { |
| father.resize(len); |
| for (int i = 0; i < len; ++i) father[i] = i; |
| sets = len; |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| bool isSameSet(int a, int b) { |
| return find(a) == find(b); |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| |
| sets--; |
| } |
| |
| int minSwapsCouples(vector<int> &row) { |
| int n = row.size(); |
| build(n / 2); |
| |
| |
| for (int i = 0; i < n; i += 2) |
| un1on(row[i] / 2, row[i + 1] / 2); |
| |
| |
| return n / 2 - sets; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> father; |
| |
| int sets; |
| |
| void build(int len) { |
| father.resize(len); |
| for (int i = 0; i < len; ++i) |
| father[i] = i; |
| sets = len; |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| bool isSameSet(int a, int b) { |
| return find(a) == find(b); |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| sets--; |
| } |
| |
| bool isSimilar(string s1, string s2) { |
| int len = s1.size(); |
| int diff = 0; |
| |
| for (int i = 0; i < len && diff < 3; ++i) |
| if (s1[i] != s2[i]) diff++; |
| return diff == 0 || diff == 2; |
| } |
| |
| int numSimilarGroups(vector<string> &strs) { |
| int len = strs.size(); |
| build(len); |
| |
| for (int i = 0; i < len; ++i) |
| for (int j = i + 1; j < len; ++j) |
| |
| if (isSimilar(strs[i], strs[j])) |
| un1on(i, j); |
| return sets; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int rows; |
| int columns; |
| vector<int> father; |
| int sets = 0; |
| |
| |
| int getIndex(int a, int b) { |
| return a * columns + b; |
| } |
| |
| void build(vector<vector<char>> &grid) { |
| father.resize(rows * columns + 1); |
| for (int i = 0; i < rows; ++i) { |
| for (int j = 0; j < columns; ++j) { |
| |
| if (grid[i][j] == '1') { |
| int index = getIndex(i, j); |
| father[index] = index; |
| sets++; |
| } |
| } |
| } |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| bool isSameSet(int a, int b) { |
| return find(a) == find(b); |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| sets--; |
| } |
| |
| int numIslands(vector<vector<char>> &grid) { |
| rows = grid.size(); |
| columns = grid[0].size(); |
| |
| build(grid); |
| |
| for (int i = 0; i < rows; ++i) { |
| for (int j = 0; j < columns; ++j) { |
| |
| if (grid[i][j] != '1') continue; |
| int index = getIndex(i, j); |
| |
| if (i > 0 && grid[i - 1][j] == '1') |
| un1on(index, getIndex(i - 1, j)); |
| |
| if (j > 0 && grid[i][j - 1] == '1') |
| un1on(index, getIndex(i, j - 1)); |
| } |
| } |
| return sets; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <unordered_map> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| |
| unordered_map<int, int> rowFirst; |
| unordered_map<int, int> colFirst; |
| vector<int> father; |
| int sets; |
| |
| void build(int len) { |
| rowFirst.clear(); |
| colFirst.clear(); |
| father.resize(len); |
| for (int i = 0; i < len; ++i) |
| father[i] = i; |
| sets = len; |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| sets--; |
| } |
| |
| int removeStones(vector<vector<int>> &stones) { |
| |
| int len = stones.size(); |
| build(len); |
| |
| for (int i = 0; i < len; ++i) { |
| int row = stones[i][0]; |
| int col = stones[i][1]; |
| |
| if (rowFirst.find(row) == rowFirst.end()) { |
| |
| rowFirst[row] = i; |
| } else { |
| |
| un1on(i, rowFirst[row]); |
| } |
| if (colFirst.find(col) == colFirst.end()) { |
| |
| colFirst[col] = i; |
| } else { |
| |
| un1on(i, colFirst[col]); |
| } |
| } |
| |
| return len - sets; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <stack> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> father; |
| |
| vector<bool> secret; |
| stack<int> stk; |
| |
| void build(int n, int firstPerson) { |
| father.resize(n); |
| secret.resize(n, false); |
| for (int i = 0; i < n; ++i) |
| father[i] = i; |
| |
| secret[0] = true; |
| secret[firstPerson] = true; |
| |
| father[firstPerson] = 0; |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| |
| secret[fb] = secret[fb] | secret[fa]; |
| } |
| |
| |
| bool knowSecret(int i) { |
| return secret[find(i)]; |
| } |
| |
| static bool cmp(vector<int> arr1, vector<int> arr2) { |
| return arr1[2] < arr2[2]; |
| } |
| |
| vector<int> findAllPeople(int n, vector<vector<int>> &meetings, int firstPerson) { |
| |
| sort(begin(meetings), end(meetings), cmp); |
| |
| |
| build(n, firstPerson); |
| |
| |
| int len = meetings.size(); |
| int i = 0; |
| int time = meetings[0][2]; |
| while (i < len) { |
| |
| while (i < len && meetings[i][2] == time) { |
| |
| stk.emplace(meetings[i][0]); |
| stk.emplace(meetings[i][1]); |
| |
| un1on(meetings[i][0], meetings[i][1]); |
| i++; |
| } |
| while (!stk.empty()) { |
| |
| if (!knowSecret(stk.top())) father[stk.top()] = stk.top(); |
| stk.pop(); |
| } |
| if (i < len) time = meetings[i][2]; |
| } |
| |
| vector<int> res; |
| |
| for (int j = 0; j < n; ++j) |
| if (knowSecret(j)) res.emplace_back(j); |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <stack> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| |
| class Solution { |
| public: |
| |
| vector<int> father; |
| |
| vector<int> cnt; |
| |
| void build(int n, vector<int> &vals) { |
| father.resize(n); |
| cnt.resize(n); |
| for (int i = 0; i < n; ++i) { |
| father[i] = i; |
| cnt[i] = 1; |
| } |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| |
| int un1on(int a, int b, vector<int> &vals) { |
| int fa = find(a); |
| int fb = find(b); |
| int path = 0; |
| |
| if (vals[fa] == vals[fb]) { |
| |
| path = cnt[fa] * cnt[fb]; |
| cnt[fb] += cnt[fa]; |
| father[fa] = fb; |
| } else if (vals[fa] > vals[fb]) { |
| father[fb] = fa; |
| } else if (vals[fa] < vals[fb]) { |
| father[fa] = fb; |
| } |
| return path; |
| } |
| |
| int numberOfGoodPaths(vector<int> &vals, vector<vector<int>> &edges) { |
| int res = vals.size(); |
| |
| |
| sort(begin(edges), end(edges), |
| [&vals](vector<int> v1, vector<int> v2) { |
| return max(vals[v1[0]], vals[v1[1]]) < max(vals[v2[0]], vals[v2[1]]); |
| }); |
| |
| build(res, vals); |
| |
| for (auto &edge: edges) |
| res += un1on(edge[0], edge[1], vals); |
| |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <stack> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<bool> virus; |
| |
| vector<int> counts; |
| |
| |
| vector<int> infect; |
| vector<int> father; |
| |
| vector<int> size; |
| |
| void build(int n, vector<int> &initial) { |
| |
| virus.resize(n, false); |
| for (auto &i: initial) |
| virus[i] = true; |
| |
| counts.resize(n, 0); |
| infect.resize(n, -1); |
| size.resize(n, 1); |
| father.resize(n); |
| for (int i = 0; i < n; ++i) |
| father[i] = i; |
| } |
| |
| int find(int i) { |
| if (i != father[i]) |
| father[i] = find(father[i]); |
| return father[i]; |
| } |
| |
| void un1on(int a, int b) { |
| int fa = find(a); |
| int fb = find(b); |
| if (fa == fb) return; |
| father[fa] = fb; |
| size[fb] += size[fa]; |
| } |
| |
| int minMalwareSpread(vector<vector<int>> &graph, vector<int> &initial) { |
| int len = graph.size(); |
| build(len, initial); |
| |
| |
| for (int i = 0; i < len; ++i) |
| for (int j = 0; j < len; ++j) |
| if (graph[i][j] == 1 && !virus[i] && !virus[j]) |
| un1on(i, j); |
| |
| for (auto &sick: initial) { |
| for (int neighbour = 0; neighbour < len; ++neighbour) { |
| |
| if (sick != neighbour && !virus[neighbour] && graph[sick][neighbour] == 1) { |
| |
| int fn = find(neighbour); |
| if (infect[fn] == -1) { |
| infect[fn] = sick; |
| } else if (infect[fn] != -2 && infect[fn] != sick) { |
| |
| infect[fn] = -2; |
| } |
| } |
| } |
| } |
| |
| |
| for (int i = 0; i < len; ++i) |
| if (i == find(i) && infect[i] >= 0) |
| counts[infect[i]] += size[i]; |
| |
| |
| sort(begin(initial), end(initial)); |
| int res = initial[0]; |
| for (auto &sick: initial) { |
| if (counts[sick] > counts[res]) |
| res = sick; |
| } |
| return res; |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18402185
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-09-07 创建型设计模式
2021-09-07 OOP七大原则