FCT
载入中...
搜索中...
未找到
UnionFind.h
浏览该文件的文档.
1//
2// Created by Administrator on 2025/8/5.
3//
4
5#ifndef UNIONFIND_H
6#define UNIONFIND_H
7#include "../ThirdParty.h"
8namespace FCT {
9 template<typename T,typename ShareType = void>
10 class UnionFind {
11 private:
12 mutable std::unordered_map<T, T> m_parent;
13 mutable std::unordered_map<T, int> m_rank;
14 mutable std::conditional_t<!std::is_void_v<ShareType>,
15 std::unordered_map<T, std::optional<ShareType>>,
17 public:
18
19 T find(const T& x) const {
20 if (m_parent.find(x) == m_parent.end()) {
21 m_parent[x] = x;
22 m_rank[x] = 0;
23 if constexpr (!std::is_void_v<ShareType>) {
24 m_sharedData[x] = std::nullopt;
25 }
26 return x;
27 }
28
29 if (m_parent[x] != x) {
30 m_parent[x] = find(m_parent[x]);
31 }
32 return m_parent[x];
33 }
34
35 bool unite(const T& x, const T& y) {
36 T rootX = find(x);
37 T rootY = find(y);
38
39 if (rootX == rootY) return false;
40
41 if (m_rank[rootX] < m_rank[rootY]) {
42 m_parent[rootX] = rootY;
43 if constexpr (!std::is_void_v<ShareType>) {
44 if (!m_sharedData[rootY].has_value() && m_sharedData[rootX].has_value()) {
45 m_sharedData[rootY] = m_sharedData[rootX];
46 }
47 }
48 } else if (m_rank[rootX] > m_rank[rootY]) {
49 m_parent[rootY] = rootX;
50 if constexpr (!std::is_void_v<ShareType>) {
51 if (!m_sharedData[rootX].has_value() && m_sharedData[rootY].has_value()) {
52 m_sharedData[rootX] = m_sharedData[rootY];
53 }
54 }
55 } else {
56 m_parent[rootY] = rootX;
57 m_rank[rootX]++;
58 if constexpr (!std::is_void_v<ShareType>) {
59 if (!m_sharedData[rootX].has_value() && m_sharedData[rootY].has_value()) {
60 m_sharedData[rootX] = m_sharedData[rootY];
61 }
62 }
63 }
64 return true;
65 }
66
67 std::unordered_map<T, std::vector<T>> getGroups() const {
68 std::unordered_map<T, std::vector<T>> groups;
69
70 for (const auto& [element, _] : m_parent) {
71 T root = find(element);
72 groups[root].push_back(element);
73 }
74
75 return groups;
76 }
77 bool connected(const T& x, const T& y) const {
78 return find(x) == find(y);
79 }
80 void shared(const T& x, const ShareType& data)
81 requires (!std::is_void_v<ShareType>)
82 {
83 T root = find(x);
84 m_sharedData[root] = data;
85 }
86
87 std::optional<ShareType> shared(const T& x) const
88 requires (!std::is_void_v<ShareType>)
89 {
90 T root = find(x);
91 auto it = m_sharedData.find(root);
92 return (it != m_sharedData.end()) ? it->second : std::nullopt;
93 }
94 };
95};// namespace FCT
96#endif //UNIONFIND_H
bool connected(const T &x, const T &y) const
bool unite(const T &x, const T &y)
std::unordered_map< T, int > m_rank
void shared(const T &x, const ShareType &data)
T find(const T &x) const
std::unordered_map< T, T > m_parent
std::unordered_map< T, std::vector< T > > getGroups() const
std::optional< ShareType > shared(const T &x) const
std::conditional_t<!std::is_void_v< ShareType >, std::unordered_map< T, std::optional< ShareType > >, char > m_sharedData