use std::collections::HashSet;

#[derive(Debug, Clone, Copy)]
pub struct Edge {
    pub weight: i32,
    pub source_id: usize,
    pub target_id: usize,
}

#[derive(Debug, Clone)]
pub struct Vertex {
    pub id: usize,
    pub edges: Vec<Edge>,
}

pub type WeightedGraph = Vec<Vertex>;

pub fn prims(graph: &WeightedGraph) -> i32 {
    let mut x: HashSet<usize> = HashSet::new();
    let mut t = Vec::new();

    x.insert(0);

    while x.len() != graph.len() {
        let mut min_edge = Edge {
            weight: i32::MAX,
            source_id: 0,
            target_id: 0,
        };

        for node_id in &x {
            for edge in &graph[*node_id].edges {
                if edge.weight < min_edge.weight && !x.contains(&edge.target_id) {
                    min_edge = *edge;
                }
            }
        }

        x.insert(min_edge.target_id);
        t.push(min_edge);
    }

    let mut result = 0;
    for edge in &t {
        result += edge.weight;
    }

    result
}
