-
Notifications
You must be signed in to change notification settings - Fork 0
/
union_find.h
94 lines (75 loc) · 1.91 KB
/
union_find.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#ifndef UNION_FIND_H_
#define UNION_FIND_H_
#include "team.h"
#include "group.h"
class UnionFind {
public:
Team** _teams;
Group** _groups;
int _size;
UnionFind(int n) : _size(n) {
_teams = new Team*[_size];
_groups = new Group*[_size];
for(int i = 0 ; i < _size ; i++) {
_teams[i] = new Team(i);
_groups[i] = new Group(_teams[i]);
}
}
Group* Find(int team) {
Team* node = _teams[team];
while(node->_father) {
node = node->_father;
}
Team* root = node;
int index = node->_number;
node = _teams[team];
while(node->_father) {
Team* tmp_father = node->_father;
node->_father = root;
node = tmp_father;
}
return _groups[index];
}
int Union(int team1, int team2) {
Team* root1 = _teams[team1];
while(root1->_father) {
root1 = root1->_father;
}
Team* root2 = _teams[team2];
while(root2->_father) {
root2 = root2->_father;
}
int size1 = _groups[root1->_number]->_size;
int size2 = _groups[root2->_number]->_size;
int trolls_number1 = _groups[root1->_number]->_trolls_number;
int trolls_number2 = _groups[root2->_number]->_trolls_number;
int group_name;
if(size1 <= size2) {
root1->_father = root2;
_groups[root1->_number]->_root = _groups[root2->_number]->_root;
_groups[root2->_number]->_size += size1;
_groups[root2->_number]->_trolls_number += trolls_number1;
root2->_group_name = root1->_group_name;
group_name = root2->_group_name;
} else {
root2->_father = root1;
_groups[root2->_number]->_root = _groups[root1->_number]->_root;
_groups[root1->_number]->_trolls_number += trolls_number2;
group_name = root1->_group_name;
}
delete _groups[root2->_group_name];
_groups[root2->_group_name] = NULL;
return group_name;
}
~UnionFind() {
for(int i = 0 ; i < _size ; i++) {
delete _teams[i];
if(_groups[i]) {
delete _groups[i];
}
}
delete[] _teams;
delete[] _groups;
}
};
#endif /* UNION_FIND_H_ */