并查集:
int par[N], rnk[N];
void init(int n)
{
for(int i = 1; i <= n; i++) par[i] = i, rnk[i] = 0;
}
int ser(int x)
{
int r = x, i = x, j;
while(r != par[r]) r = par[r];
while(par[i] != r) j = par[i], par[i] = r, i = j;
return r;
}
void unite(int x, int y) //启发式按秩合并,当然也可以取消秩合并
{
x = ser(x), y = ser(y);
if(x == y) return;
if(rnk[x] > rnk[y]) par[y] = x;
else
{
par[x] = y;
if(rnk[x] == rnk[y]) rnk[y]++;
}
}
bool same(int x, int y)
{
return ser(x) == ser(y);
}