Skip to content

Added make_root in DSU #342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions pydatastructs/miscellaneous_data_structures/disjoint_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class DisjointSetForest(object):
>>> dst.union(1, 2)
>>> dst.find_root(2).key
1
>>> dst.make_root(2)
>>> dst.find_root(2).key
2

References
==========
Expand Down Expand Up @@ -74,3 +77,29 @@ def union(self, key1, key2):

y_root.parent = x_root
x_root.size += y_root.size

def make_root(self, key):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature looks good. Could you share an example (book/lecture notes examples will work) where this is used/required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presently, I don't remember the exact the example but, we can consider this example https://cp-algorithms.com/data_structures/disjoint_set_union.html#toc-tgt-10 wherein we generally make root which Is largest element in set

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. That's great. Could you solve one such problem using DSU API in pydatastructs and show the code here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will trying finding the exact problem I solved using this method and show that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is the problem where I used the above method: https://codeforces.com/contest/1133/problem/F2, and the submission of mine can be found at: https://codeforces.com/contest/1133/submission/109674863

"""
Finds the set to which the key belongs
and makes it as the root of the set.
"""
if self.tree.get(key, None) is None:
raise KeyError("Invalid key, %s"%(key))

key_set = self.tree[key]
if key_set.parent is not key_set:
current_parent = key_set.parent
# Remove this key subtree size from all its ancestors
while current_parent.parent is not current_parent:
current_parent.size -= key_set.size
current_parent = current_parent.parent

all_set_size = current_parent.size # This is the root node
current_parent.size -= key_set.size

# Make parent of current root as key
current_parent.parent = key_set
# size of new root will be same as previous root's size
key_set.size = all_set_size
# Make parent of key as itself
key_set.parent = key_set
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,44 @@ def test_DisjointSetForest():
assert raises(KeyError, lambda: dst.find_root(9))
dst.union(3, 1)
assert dst.find_root(3).key == 1
assert dst.find_root(5).key == 1
dst.make_root(6)
assert dst.find_root(3).key == 6
assert dst.find_root(5).key == 6
dst.make_root(5)
assert dst.find_root(1).key == 5
assert dst.find_root(5).key == 5
assert raises(KeyError, lambda: dst.make_root(9))

dst = DisjointSetForest()
for i in range(6):
dst.make_set(i)
assert dst.tree[2].size == 1
dst.union(2, 3)
assert dst.tree[2].size == 2
assert dst.tree[3].size == 1
dst.union(1, 4)
dst.union(2, 4)
# current tree
###############
# 2
# / \
# 1 3
# /
# 4
###############
assert dst.tree[2].size == 4
assert dst.tree[1].size == 2
assert dst.tree[3].size == dst.tree[4].size == 1
dst.make_root(4)
# New tree
###############
# 4
# |
# 2
# / \
# 1 3
###############
assert dst.tree[4].size == 4
assert dst.tree[2].size == 3
assert dst.tree[1].size == dst.tree[3].size == 1