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 Scala (2.11.7) (judge verdict: Accepted)

object Main {

  def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ArrayBuffer
    val sc = new java.util.Scanner(System.in)

    // 方向性
    // Bellman-Fordアルゴリズムによって, 全ての頂点vについて, 到達可能な異なる頂点への単一始点最短路を解く.
    // Bellman-FordアルゴリズムはO(VE)なので, 全ての頂点について調べると全点対最短路を解くことになりO(V^2E)である.
    // この時点で全点最短路が求まっているので, 任意のu of Vについて,
    // v of {V - u (d(u,v) != ∞) } からu に到達するために先行点を手繰って通る辺は最短路であるから, この時の最短路を数えていく.
    // 同様の辺を通ることがあるから, ユニークな数を数える.

    val N, M = sc.nextInt()

    val MINF = Int.MinValue / 10
    val INF = Int.MaxValue / 10

    // 全て親が存在しないものとする.
    // parent(u)(v) (u != v) は u について v への推定最短路を達成する v の先行点.
    // u についての v の推定最短路を達成する全ての辺はv の先行点を辿ることで列挙できる.
    val parent = Array.fill(N+1, N+1)(MINF)
    // 全ての距離を∞に初期化する. distance(u)(v) (u != v) はuからvへの推定最短路.
    // アルゴリズムが収束した時, distance(u)(v) = δ(u, v) となり, 最短路の値となる.
    // この時, u についての最短路ではparent(v) を起点としてuまで
    val distance = Array.fill(N+1, N+1)(INF)
    (1 to N) foreach { i => // 全ての自分自身への距離を0とする.
      distance(i)(i) = 0
    }
    // weight(u, v) は u から vへの重さ
    val weight = Array.fill(N+1, N+1)(INF)

    val E = new ArrayBuffer[(Int, Int)]()
    (0 until M) foreach { _ =>
      val a, b, c = sc.nextInt()
      weight(a)(b) = c
      weight(b)(a) = c
      E.append((a, b), (b, a))
    }

    // 全ての頂点について, ベルマンフォードの緩和のステップを行う.
    // ここで, 負閉路がないことが前提なので, 負閉路の判定のステップは必要がない.
    (1 to N) foreach { i =>
      (1 until N) foreach { _ =>
        E foreach { case (u, v) =>
          if (distance(i)(v) > distance(i)(u) + weight(u)(v)) {
            distance(i)(v) = distance(i)(u) + weight(u)(v)
            parent(i)(v) = u
          }
        }
      }
    }

    // 全ての頂点について, 異なる頂点への最短路を逆方向に辿って最短路をカウントしていく.
    val b = Set.newBuilder[(Int, Int)]
    (1 to N) foreach { u =>
      (1 to N) foreach { v =>
        var _v = v
        while (parent(u)(_v) != MINF) {
          b += (if (parent(u)(_v) < _v) (parent(u)(_v), _v) else (_v, parent(u)(_v)))
          _v = parent(u)(_v)
        }
      }
    }

    // ユニークな最短路に使った辺の数を全体の辺の数から引くと, 使わなかった辺の数になる.
    println(M - b.result().size)
  }
}