pub struct ProconReader { reader: R, } impl ProconReader { pub fn new(reader: R) -> Self { Self { reader } } pub fn get(&mut self) -> T { use std::io::Read; let buf = self .reader .by_ref() .bytes() .map(|b| b.unwrap()) .skip_while(|&byte| byte == b' ' || byte == b'\n' || byte == b'\r') .take_while(|&byte| byte != b' ' && byte != b'\n' && byte != b'\r') .collect::>(); std::str::from_utf8(&buf) .unwrap() .parse() .ok() .expect("Parse Error.") } } #[allow(dead_code)] mod mint { use std::ops::{Add, BitAnd, Div, Mul, Rem, Shr, Sub}; #[derive(Copy, Clone)] pub struct Mint { x: T, mo: T, } impl Mint where T: Copy, { pub fn new(x: T, mo: T) -> Mint { Mint { x, mo } } } impl Mint where T: Copy, { pub fn val(&self) -> T { self.x } pub fn mo(&self) -> T { self.mo } } impl Add for Mint where T: Copy, T: Add, T: Rem, { type Output = Mint; fn add(self, rhs: T) -> Mint { Mint::new((self.val() + rhs % self.mo()) % self.mo(), self.mo()) } } impl Add> for Mint where T: Copy, Mint: Add>, { type Output = Mint; fn add(self, rhs: Mint) -> Mint { self + rhs.val() } } impl Sub for Mint where T: Copy, T: Add, T: Sub, T: Rem, { type Output = Mint; fn sub(self, rhs: T) -> Mint { Mint::new( (self.val() + self.mo() - rhs % self.mo()) % self.mo(), self.mo(), ) } } impl Sub> for Mint where T: Copy, Mint: Sub>, { type Output = Mint; fn sub(self, rhs: Mint) -> Mint { self - rhs.val() } } impl Mul for Mint where T: Copy, T: Mul, T: Rem, { type Output = Mint; fn mul(self, rhs: T) -> Mint { Mint::new((self.val() * rhs % self.mo()) % self.mo(), self.mo()) } } impl Mul> for Mint where T: Copy, Mint: Mul>, { type Output = Mint; fn mul(self, rhs: Mint) -> Mint { self * rhs.val() } } impl Mint where T: Copy, T: Sub, T: Div, T: PartialOrd, T: PartialEq, T: BitAnd, T: Shr, Mint: Mul>, { pub fn pow(self, y: T) -> Mint { let one = self.mo() / self.mo(); let zero = self.mo() - self.mo(); let mut res = Mint::one(self.mo()); let mut base = self; let mut exp = y; while exp > zero { if (exp & one) == one { res = res * base; } base = base * base; exp = exp >> one; } res } } impl Div for Mint where T: Copy, T: Sub, T: Div, T: PartialOrd, T: PartialEq, T: BitAnd, T: Shr, Mint: Mul>, { type Output = Mint; fn div(self, rhs: T) -> Mint { let one = self.mo() / self.mo(); self * Mint::new(rhs, self.mo()).pow(self.mo() - one - one) } } impl Div> for Mint where T: Copy, Mint: Div>, { type Output = Mint; fn div(self, rhs: Mint) -> Mint { self / rhs.val() } } impl Mint where T: Copy, T: Div, Mint: Div>, { pub fn inv(self) -> Mint { Mint::one(self.mo()) / self } } impl std::fmt::Display for Mint where T: Copy + std::fmt::Display, { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.val()) } } impl Mint where T: Copy, T: Sub, { pub fn zero(mo: T) -> Mint { Mint { x: mo - mo, mo } } } impl Mint where T: Copy, T: Div, { pub fn one(mo: T) -> Mint { Mint { x: mo / mo, mo } } } } use mint::Mint; pub struct UnionFind { par: Vec, size: Vec, } impl UnionFind { pub fn new(n: usize) -> UnionFind { UnionFind { par: (0..n).map(|i| i).collect::>(), size: vec![1; n], } } pub fn find(&mut self, i: usize) -> usize { if self.par[i] == i { self.par[i] } else { self.par[i] = self.find(self.par[i]); self.par[i] } } pub fn unite(&mut self, i: usize, j: usize) { let i = self.find(i); let j = self.find(j); if i == j { return; } let (i, j) = if self.size[i] >= self.size[j] { (i, j) } else { (j, i) }; self.par[j] = i; self.size[i] += self.size[j]; } pub fn same(&mut self, i: usize, j: usize) -> bool { self.find(i) == self.find(j) } pub fn get_size(&mut self, i: usize) -> usize { let p = self.find(i); self.size[p] } } #[derive(Debug, Clone)] struct Edge { to: usize, cost: i64, } fn minimum_spanning_tree(g: &Vec>) -> Option>> { let n = g.len(); let mut edges = vec![]; for i in 0..n { for e in &g[i] { edges.push((e.cost, i, e.to)); } } edges.sort(); let mut result = vec![vec![]; n]; let mut uf = UnionFind::new(n); let mut count = 0; for e in edges { let (c, from, to) = e; if !uf.same(from, to) { uf.unite(from, to); count += 1; result[from].push(Edge { to: to, cost: c }); result[to].push(Edge { to: from, cost: c }); } } if count == n - 1 { Some(result) } else { assert!(count < n - 1); None } } fn dfs(g: &Vec>, i: usize, p: usize, size: &mut Vec) { size[i] = 1; for e in &g[i] { if e.to != p { dfs(g, e.to, i, size); size[i] += size[e.to]; } } } fn main() { let stdin = std::io::stdin(); let mut rd = ProconReader::new(stdin.lock()); let n: usize = rd.get(); let m: usize = rd.get(); let x: usize = rd.get(); let mut g = vec![vec![]; n]; for _ in 0..m { let u: usize = rd.get(); let v: usize = rd.get(); let w: i64 = rd.get(); g[u - 1].push(Edge { to: v - 1, cost: w }); g[v - 1].push(Edge { to: u - 1, cost: w }); } let h = minimum_spanning_tree(&g).unwrap(); let mut size = vec![0; n]; dfs(&h, 0, !0, &mut size); let mut q = std::collections::VecDeque::new(); q.push_back((0, !0, 0, 0)); let mo = 1_000_000_000 + 7; let mut ans = Mint::zero(mo); while let Some((i, p, c, acc)) = q.pop_front() { if p != !0 { ans = ans + Mint::new(size[i] * acc, mo) * Mint::new(x, mo).pow(c); } let mut a = acc + 1; for e in &h[i] { if e.to != p { a += size[e.to]; } } for e in &h[i] { if e.to != p { q.push_back((e.to, i, e.cost as usize, a - size[e.to])); } } } println!("{}", ans); }