В процессе find(x) мы не просто находим представителя, но и после этого подвешиваем все пройденные вершины к нему. Эта процедура называется two-pass method: мы делаем сразу 2 действия (найти родителя, возвращаемся назад (т.е. рекурсии заканчиваются) и подвешиваем к корню текущие вершины)
int find(x) {
if (arr[x] == x) {
return x;
}
arr[x] = find(arr[x]); // подвешиваем текущий к представителю, которого найдём рекурсивно
return arr[x];
}