Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <cstring>
- #include <cmath>
- using std::strcmp;
- using std::ifstream;
- using std::ofstream;
- using std::min;
- struct List {
- int value;
- int min_item;
- int size;
- List * parent;
- };
- class DSU {
- private:
- List * items;
- int itemNum;
- List& getParent(List &item);
- public:
- DSU (int N) {
- items = new List[N];
- for (int i=0; i<N; i++) {
- items[i].parent = &items[i];
- items[i].value = i+1;
- items[i].size = 1;
- items[i].min_item = items[i].value;
- }
- itemNum = N;
- }
- void merge(int first, int second);
- int get(int item);
- };
- List& DSU::getParent(List &item) {
- if (item.parent == &item) {
- return item;
- }
- item.parent = &getParent(*item.parent);
- return *item.parent;
- }
- void DSU::merge(int first, int second) {
- List &firstItem = getParent(items[first]);
- List &secondItem = getParent(items[second]);
- if (firstItem.value == secondItem.value)
- return;
- if (&firstItem.size <= &secondItem.size) {
- firstItem.parent = &secondItem;
- secondItem.min_item = min(firstItem.min_item, secondItem.min_item);
- secondItem.size += firstItem.size;
- } else {
- secondItem.parent = &firstItem;
- firstItem.min_item = min(firstItem.min_item, secondItem.min_item);
- firstItem.size += secondItem.size;
- }
- }
- int DSU::get(int item) {
- return getParent(items[item]).min_item;
- }
- int main() {
- ifstream input("dsu.in", std::ios::in);
- ofstream output("dsu.out", std::ios::out);
- int N;
- input >> N;
- DSU dsu(N);
- while (!input.eof()) {
- char * cmd = new char[255];
- input >> cmd;
- if (strcmp(cmd, "union")==0) {
- int first, second;
- input >> first >> second;
- dsu.merge(first-1, second-1);
- }
- if (strcmp(cmd, "get")==0) {
- int item;
- input >> item;
- output << dsu.get(item-1) << std::endl;
- }
- delete cmd;
- }
- input.close();
- output.close();
- return 0;
- }
Add Comment
Please, Sign In to add comment