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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AtTest.Dijkstra
{
    class ABC_051
    {
        static Node[] nodes;
        static Dictionary<int, bool> usedDict;

        static void Main(string[] args)
        {
            Method(args);
            Console.ReadLine();
        }

        static void Method(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int n = int.Parse(input[0]);
            int m = int.Parse(input[1]);

            nodes = new Node[n];
            for (int i = 0; i < n; i++)
            {
                nodes[i] = new Node(n);
                nodes[i].distances[i] = 0;
                nodes[i].isMin[i] = true;
            }

            for (int i = 0; i < m; i++)
            {
                string[] nodeInput = Console.ReadLine().Split(' ');
                int n1 = int.Parse(nodeInput[0]) - 1;
                int n2 = int.Parse(nodeInput[1]) - 1;
                int t = int.Parse(nodeInput[2]);
                nodes[n1].edges.Add(new Edge(n2, t, i));
                nodes[n2].edges.Add(new Edge(n1, t, i));
            }

            usedDict = new Dictionary<int, bool>();
            for (int i = 0; i < n; i++)
            {
                Dijkstra(i);
                /*for(int j = 0; j < n; j++)
                {
                    Console.Write(nodes[i].distances[j] + " ");
                }
                Console.WriteLine();*/
            }
            
            /*for(int i = 0; i < n-1; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    int now = j;
                    while (now != i)
                    {
                        int next = now;
                        int edgeId = -1;
                        for (int k = 0; k < nodes[now].edges.Count; k++)
                        {
                            int index = nodes[now].edges[k].toIndex;
                            if (nodes[i].distances[index]
                                < nodes[i].distances[next])
                            {
                                next = k;
                                edgeId = nodes[now].edges[k].id;
                            }
                        }
                        if (!usedDict.ContainsKey(edgeId))
                        {
                            usedDict.Add(edgeId, true);
                        }
                        Console.WriteLine(edgeId);
                        now = next;
                    }
                }
            }*/
            Console.WriteLine(m - usedDict.Count);
        }

        //最大距離を帰す
        static long Dijkstra(int start)
        {
            Node startNode = nodes[start];
            int cnt = 1;
            int nowIndex = start;

            while (cnt < nodes.Length)
            {
                Node nowNode = nodes[nowIndex];
                for (int i = 0; i < nowNode.edges.Count; i++)
                {
                    int destIndex = nowNode.edges[i].toIndex;
                    if (startNode.isMin[destIndex]) continue;//確定ノードは無視

                    long distance = startNode.distances[nowIndex]
                        + nowNode.edges[i].distance;
                    if (distance < startNode.distances[destIndex]
                        || startNode.distances[destIndex] == -1)
                    {
                        startNode.distances[destIndex] = distance;
                    }
                }

                int settleIndex = -1;
                for (int i = 0; i < startNode.distances.Length; i++)
                {
                    if (startNode.isMin[i] || startNode.distances[i] == -1) continue;

                    if (settleIndex == -1
                        || startNode.distances[i] < startNode.distances[settleIndex])
                    {
                        settleIndex = i;
                    }
                }
                if (settleIndex == -1) break;

                startNode.isMin[settleIndex] = true;
                nowIndex = settleIndex;
                cnt++;
                for (int i = 0; i < nodes[nowIndex].edges.Count; i++)
                {
                    int pair = nodes[nowIndex].edges[i].toIndex;
                    if (!usedDict.ContainsKey(nodes[nowIndex].edges[i].id)
                        && startNode.isMin[pair]
                        && startNode.distances[nowIndex]
                        == startNode.distances[pair]
                        + nodes[nowIndex].edges[i].distance)
                    {
                        usedDict.Add(nodes[nowIndex].edges[i].id, true);
                        break;
                    }
                }
            }
            return startNode.distances[nowIndex];
        }

        class Node
        {
            public long[] distances;
            public bool[] isMin;
            public List<Edge> edges;
            public Node(int length)
            {
                distances = new long[length];
                isMin = new bool[length];
                for (int i = 0; i < length; i++)
                {
                    distances[i] = -1;
                }
                edges = new List<Edge>();
            }
        }

        class Edge
        {
            public int toIndex;
            public int distance;
            public int id;

            public Edge(int toIndex, int distance,int id)
            {
                this.toIndex = toIndex;
                this.distance = distance;
                this.id = id;
            }
        }
    }
}