Problem:
Score : 400 points

Problem Statement

You are given an undirected connected weighted graph with N vertices and M edges that contains neither self-loops nor double edges.

The i-th (1≤i≤M) edge connects vertex a_i and vertex b_i with a distance of c_i.

Here, a self-loop is an edge where a_i = b_i (1≤i≤M), and double edges are two edges where (a_i,b_i)=(a_j,b_j) or (a_i,b_i)=(b_j,a_j) (1≤i<j≤M).

A connected graph is a graph where there is a path between every pair of different vertices.

Find the number of the edges that are not contained in any shortest path between any pair of different vertices.

Constraints

2≤N≤100

N-1≤M≤min(N(N-1)/2,1000)

1≤a_i,b_i≤N

1≤c_i≤1000

c_i is an integer.

The given graph contains neither self-loops nor double edges.

The given graph is connected.

Input

The input is given from Standard Input in the following format:

N M
a_1 b_1 c_1
a_2 b_2 c_2
:
a_M b_M c_M

Output

Print the number of the edges in the graph that are not contained in any shortest path between any pair of different vertices.

Sample Input 1

3 3
1 2 1
1 3 1
2 3 3

Sample Output 1

1

In the given graph, the shortest paths between all pairs of different vertices are as follows:

The shortest path from vertex 1 to vertex 2 is: vertex 1 → vertex 2, with the length of 1.

The shortest path from vertex 1 to vertex 3 is: vertex 1 → vertex 3, with the length of 1.

The shortest path from vertex 2 to vertex 1 is: vertex 2 → vertex 1, with the length of 1.

The shortest path from vertex 2 to vertex 3 is: vertex 2 → vertex 1 → vertex 3, with the length of 2.

The shortest path from vertex 3 to vertex 1 is: vertex 3 → vertex 1, with the length of 1.

The shortest path from vertex 3 to vertex 2 is: vertex 3 → vertex 1 → vertex 2, with the length of 2.

Thus, the only edge that is not contained in any shortest path, is the edge of length 3 connecting vertex 2 and vertex 3, hence the output should be 1.

Sample Input 2

3 2
1 2 1
2 3 1

Sample Output 2

0

Every edge is contained in some shortest path between some pair of different vertices.

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::vec::Vec;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}

fn read_touple2<T: std::str::FromStr + Copy>() -> (T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 2);
  (v[0], v[1])
}

fn read_touple3<T: std::str::FromStr + Copy>() -> (T, T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 3);
  (v[0], v[1], v[2])
}

fn main() {
  let (n, m) = read_touple2::<usize>();

  let mut g = Vec::new();
  for _ in 0..m {
    let i = read_touple3::<usize>();
    g.push(i);
  }

  let (dist, paths) = warshal_floyd_path(n, &g, false);

  // for v in &dist {
  //   println!("{:?}", v);
  // }
  // println!("");

  // for v in &paths {
  //   println!("{:?}", v);
  // }

  // for i in 0..n {
  //   for j in 0..n {
  //     let shortest_path = path_print(&paths, i, j);
  //     print!("{} to {}: ", i, j);
  //     println!("{:?}", shortest_path);
  //     // for i in 0..shortest_path.len() {
  //     //   print!("{} -> ", shortest_path[i] + 1);
  //     // }
  //   }
  // }

  let mut p = vec![vec![0; n]; n];
  for i in 0..n-1 {
    for j in i+1..n {
      let shortest_path = path_print(&paths, i, j);
      for k in 0..shortest_path.len()-1 {
        let from = shortest_path[k];
        let to = shortest_path[k+1];
        p[from][to] = 1;
      }
    }
  }
  let mut ans = 0;
  for i in 0..n-1 {
    for j in i+1..n {
      if p[i][j] > 0 {
         ans += 1;
      }
    }
  }

  println!("{}", m-ans);
}


//
// O(V^3)
fn warshal_floyd_path(
  n: usize,
  v: &Vec<(usize, usize, usize)>,
  direct: bool,
) -> (Vec<Vec<usize>>, Vec<Vec<usize>>) {
  let mut dist = vec![vec![std::usize::MAX / 2; n]; n];
  let mut next = vec![vec![0; n]; n];
  // init
  for &(x, y, c) in v {
    dist[x-1][y-1] = c;
    if !direct {
      dist[y-1][x-1] = c;
    }
  }

  // 復元用のマトリックスの初期化
  for i in 0..n {
    for j in 0..n {
      next[i][j] = j;
    }
  }

  for k in 0..n {
    for i in 0..n {
      for j in 0..n {
        if dist[i][j] > dist[i][k] + dist[k][j] {
          dist[i][j] = dist[i][k] + dist[k][j];
          next[i][j] = next[i][k];
        }
      }
    }
  }
  (dist, next)
}

// 経路復元用のの関数
// O(V)
fn path_print(paths: &Vec<Vec<usize>>, start: usize, goal: usize) -> Vec<usize> {
  let mut res = Vec::new();
  let mut cur = start;
  while {
    cur != goal
  } {
    res.push(cur);
    cur = paths[cur][goal];
  }
  res.push(goal);
  //println!("{:?}", res);
  res
}