# Why does this union-find cycle check miss some redundant edges?

**URL:** <https://forum.kirupa.com/t/why-does-this-union-find-cycle-check-miss-some-redundant-edges/680019>\
**Category:** web dev\
**Created:** [April 5, 2026, 3:00am UTC](https://forum.kirupa.com/t/why-does-this-union-find-cycle-check-miss-some-redundant-edges/680019 "2026-04-05T03:00:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Quelly](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/quelly/32/31386_2.png) [@Quelly](https://forum.kirupa.com/u/Quelly)\
**Post date:** [April 5, 2026, 3:00am UTC](https://forum.kirupa.com/t/why-does-this-union-find-cycle-check-miss-some-redundant-edges/680019/1 "2026-04-05T03:00:10Z")

</div>

I’m using union-find to detect the first edge that creates a cycle in an undirected graph, but this sometimes returns null even when a cycle exists. I suspect the issue is in how parents are updated during union. What is wrong here?

```js
function hasCycle(edges, n) {
  const p = Array.from({ length: n }, (_, i) => i);
  const find = x => p[x] === x ? x : find(p[x]);
  for (const [a, b] of edges) {
    if (find(a) === find(b)) return [a, b];
    p[a] = b;
  }
  return null;
}

```

Quelly

---

<div class="post-metadata">

**Author:** ![Ellen1979](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/ellen1979/32/31260_2.png) [@Ellen1979](https://forum.kirupa.com/u/Ellen1979)\
**Post date:** [April 5, 2026, 3:14am UTC](https://forum.kirupa.com/t/why-does-this-union-find-cycle-check-miss-some-redundant-edges/680019/2 "2026-04-05T03:14:05Z")

</div>

@Quelly, the bad line is `p[a] = b

```js
because it links raw vertices instead of linking the two set roots, so earlier structure can get overwritten and the cycle check goes blind;
a quick debug signal is printing

```

find(a), find(b), p.slice()` after each edge and you’ll see parents stop representing components.

Ellen 😊
