Friend Circle Queries

  • + 0 comments

    modified to prevent memory issues from creating a vector of size 10^9

    class disjoint_set {
    public:
        vector<int> parent = { 0 }, size = { 0 };
        disjoint_set(int n) {
            for (int i = 1; i <= n; i++) {
                parent.push_back(i);
                size.push_back(1);
            }
        }
        int find(int x) {
            if (x != parent[x]) parent[x] = find(parent[x]);
            return parent[x];
        }
        void Union(int x, int y) {
            int xRep = find(x), yRep = find(y);
            if (xRep == yRep) return;
            if (size[xRep] <= size[yRep]) {
                parent[xRep] = yRep;
                size[yRep] = size[yRep] + size[xRep];
            }
            else {
                parent[yRep] = xRep;
                size[xRep] = size[xRep] + size[yRep];
            }
        }
    };
    
    vector<int> maxCircle(const vector<int>& people, const vector<vector<int>>& queries) {
        disjoint_set world(people.size());
        vector<int> result;
        int largest = 1;
        for (auto q : queries) {
            auto it0 = lower_bound(people.begin(), people.end(), q[0]);
            auto it1 = lower_bound(people.begin(), people.end(), q[1]);
            int p0 = it0 - people.begin() + 1, p1 = it1 - people.begin() + 1;
            world.Union(p0, p1);
            int x = world.find(p0), y = world.find(p1);
            largest = max({largest, world.size[x], world.size[y]});
            result.push_back(largest);
        }
        return result;
    }
    
    int main()
    {
        int q, k, l = 0;
        vector<vector<int>> queries;
        set<int> S;
        vector<int> people;
        cin >> q;
        for (int i=1; i <= q; ++i) {
            cin >> k >> l;
            S.insert(k);
            S.insert(l);
            queries.push_back({k, l});
        }
        people.assign(S.begin(), S.end());
        auto X = maxCircle(people, queries);
        for (int x : X) cout << x << '\n';
    }