Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- class DSU {
- std::vector<int> dsu;
- std::vector<int> sizes;
- std::vector<bool> is_root;
- std::vector<int> smallest;
- std::vector<int> depth;
- int result = 0;
- bool updated = true;
- public:
- DSU(int n) {
- for (int i = 0; i < n; ++i) {
- dsu.push_back(i);
- smallest.push_back(i);
- }
- sizes.resize(n, 1);
- depth.resize(n, 0);
- is_root.resize(n, true);
- }
- int find_root(int a) {
- if (dsu[a] == a) {
- return a;
- }
- return dsu[a] = find_root(dsu[a]);
- }
- void union_dsu(int a, int b) {
- a = find_root(a);
- b = find_root(b);
- if (a != b) {
- updated = false;
- if (depth[b] < depth[a]) {
- dsu[b] = a;
- sizes[a] += sizes[b];
- is_root[b] = false;
- smallest[a] = std::min(smallest[a], smallest[b]);
- } else {
- dsu[a] = b;
- sizes[b] += sizes[a];
- is_root[a] = false;
- smallest[b] = std::min(smallest[a], smallest[b]);
- if (depth[b] == depth[a]) {
- depth[b]++;
- }
- }
- }
- }
- int city() {
- if (updated) {
- if (result == -1) {
- return -1;
- }
- return result + 1;
- }
- int res = dsu.size();
- for (int i = 0; i < dsu.size(); ++i) {
- if (is_root[i] && sizes[i] % 2 == 1 && smallest[i] < res) {
- res = smallest[i];
- }
- }
- updated = true;
- if (res == dsu.size()) {
- result = -1;
- return -1;
- } else {
- result = res;
- return result + 1;
- }
- }
- };
- int main() {
- int n, m;
- std::cin >> n >> m;
- DSU dsu(n);
- char command;
- int a, b;
- for (int i = 0; i < m; ++i) {
- std::cin >> command;
- if (command == 'a') {
- std::cin >> a >> b;
- dsu.union_dsu(a - 1, b - 1);
- } else {
- std::cout << dsu.city() << '\n';
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement