Regular Union-Find practice one.
#include <cmath> #include <cstdio> #include <climits> #include <vector> #include <iostream> #include <fstream> #include <algorithm> #include <unordered_set> #include <unordered_map> using namespace std; unordered_map<int, int> ps; // for id unordered_map<int, unsigned> us; // for sets int id(int v) { if(!ps.count(v)) return -1; while(ps[v] != v) v = ps[v]; return v; } bool find_(int p0, int p1) { return id(p0) == id(p1) && id(p0) != -1; } void union_(int v0, int v1) { int p0 = id(v0), p1 = id(v1); if(p0 != -1 && p1 != -1) // 2 existing sets { if(p0 != p1) { int sp = min(p0, p1); int sl = max(p0, p1); ps[sl] = sp; us[sp] += us[sl]; us.erase(sl); } } else // 1 is wild { int pv = p0 != -1 ? p0 : p1; int wv = p0 == -1 ? v0 : v1; ps[wv] = pv; us[pv]++; } } int main() { int n; cin >> n; while(n--) { int a, b; cin >> a >> b; int s = min(a, b), l = max(a, b); int is = id(s), il = id(l); if(is == -1 && il == -1) { ps[l] = ps[s] = s; us[s] = 2; } else { if(!find_(s, l)) { union_(s, l); } } } unsigned minv = INT_MAX, maxv = 0; for(auto &kv: us) { maxv = max(maxv, kv.second); minv = min(minv, kv.second); } cout << minv << " " << maxv << endl; return 0; }