Problem:
Minimum Spanning Tree

Find the sum of weights of edges of the Minimum Spanning Tree for a given weighted undirected graph G = (V, E).

Input

|V| |E|
s0 t0 w0
s1 t1 w1
:
s|E|-1 t|E|-1 w|E|-1

, where |V| is the number of vertices and |E| is the number of edges in the graph. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target verticess of i-th edge (undirected) and wi represents the weight of the i-th edge.

Output

Print the sum of the weights of the Minimum Spanning Tree.

Constraints

1 ≤ |V| ≤ 10,000

0 ≤ |E| ≤ 100,000

0 ≤ wi ≤ 10,000

The graph is connected

There are no parallel edges

There are no self-loops

Sample Input 1

4 6
0 1 2
1 2 1
2 3 1
3 0 1
0 2 3
1 3 5

Sample Output 1

3

Sample Input 2

6 9
0 1 1
0 2 3
1 2 1
1 3 7
2 4 1
1 4 3
3 4 1
3 5 1
4 5 6

Sample Output 2

5

Solution in Rust (judge verdict: Accepted)

use std::collections::BinaryHeap;

#[derive(Debug, Clone, Copy)]
struct Edge {
    from: usize,
    to: usize,
    weight: i64,
}

use std::cmp;
use std::cmp::Ordering;
impl cmp::Ord for Edge {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.weight.cmp(&other.weight) {
            Ordering::Equal => Ordering::Equal,
            Ordering::Less => Ordering::Greater,
            Ordering::Greater => Ordering::Less,
        }
    }
}

impl cmp::PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl cmp::Eq for Edge {}

impl cmp::PartialEq for Edge {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}

impl Edge {
    fn new(from: usize, to: usize, weight: i64) -> Self {
        Self { from, to, weight }
    }
}

fn solve(graph: Vec<Vec<(usize, i64)>>) {
    let size = graph.len();
    let mut is_in_tree: Vec<bool> = vec![false; size];
    let mut num_of_nodes = 0;
    let mut edges = BinaryHeap::new();
    let mut min_weight = 0;
    // Initialize
    is_in_tree[0] = true;
    num_of_nodes += 1;
    for &(to, weight) in &graph[0] {
        edges.push(Edge::new(0, to, weight));
    }
    while num_of_nodes < size {
        let Edge { from, to, weight } = edges.pop().unwrap();
        if is_in_tree[to] {
            continue;
        } else {
            is_in_tree[to] = true;
            num_of_nodes += 1;
            min_weight += weight;
            for &(to, weight) in &graph[to] {
                edges.push(Edge::new(from, to, weight));
            }
        }
    }
    println!("{}", min_weight);
}

use std::io::{BufRead, BufReader};
fn main() {
    let mut read = BufReader::new(std::io::stdin())
        .lines()
        .filter_map(|e| e.ok());
    let (v, _e) = {
        let line = read.next().unwrap();
        let line: Vec<&str> = line.split(' ').collect();
        let v: usize = line[0].parse().unwrap();
        let e: usize = line[1].parse().unwrap();
        (v, e)
    };
    let graph = {
        let mut graph: Vec<Vec<_>> = vec![vec![]; v]; // Adj list
        for edge in read {
            if edge.is_empty() {
                break;
            }
            let mut edge = edge.split(' ');
            let start: usize = edge.next().unwrap().parse().unwrap();
            let end: usize = edge.next().unwrap().parse().unwrap();
            let weight: i64 = edge.next().unwrap().parse().unwrap();
            graph[start].push((end, weight));
            graph[end].push((start,weight));
        }
        graph
    };
    solve(graph);
}