///|
fn root(parent : Array[Int32], start : Int32) -> Int32 {
let mut x = start
while parent[x] != x {
x = parent[x]
}
x
}
///|
/// Edge IDs are stable, including loops and parallel edges. Vertices <=256.
pub fn Matroid::graphic(
vertices : Int32,
edges : Array[(Int32, Int32)],
) -> Matroid raise MatroidError {
check_size(edges.length())
if vertices < 0 || vertices > 256 {
raise InvalidInput("vertices outside 0..256")
}
for edge in edges {
let (u, v) = edge
if u < 0 || v < 0 || u >= vertices || v >= vertices {
raise InvalidInput("edge endpoint outside graph")
}
}
let owned = edges.copy()
{
size: owned.length(),
model: "graphic",
evaluate: xs => {
let parents = all_elements(vertices)
let sizes = Array::make(vertices, 1)
let mut rank = 0
for e in xs {
let (u, v) = owned[e]
let a = root(parents, u)
let b = root(parents, v)
if a != b {
if sizes[a] < sizes[b] {
parents[a] = b
sizes[b] = sizes[b] + sizes[a]
} else {
parents[b] = a
sizes[a] = sizes[a] + sizes[b]
}
rank = rank + 1
}
}
rank
},
}
}