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: Wrong Answer)

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

namespace Equeue
{
    
    
    class Equeue
    {
        static Dictionary<long,long> Primes;
        
        static void Main(string[] args)
        {
            var NA = 10000;
            var NM = Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToArray();
            var N = NM[0];
            var M = NM[1];
            
            var V = new long[N+1,N+1];
            var G = new long[N+1,N+1];
            
            for(int i = 0;i < M;i++){
                var ABC = Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToArray();
                var A = ABC[0];
                var B = ABC[1];
                var C = ABC[2];
                
                V[A,B] = C;
                V[B,A] = C;
                G[A,B] = C;
                G[B,A] = C;
            }
            
            for(int i = 1;i <= N;i++){
                    for(int j = 1;j <= N;j++){
                        if(i != j)
                        {
                        V[i, j] = NA;
                        G[i, j] = NA;

                    }

                        
                    }
            }  
            
            for(int k = 1;k <= N;k++){
                for(int i = 1;i <= N;i++){
                    for(int j = 1;j <= N;j++){
                        if(G[i,j] > G[i,k] + G[k,j]){
                            G[i,j] = G[i,k] + G[k,j];
                        }
                    }
                }
            }
            
            long ans = 2*M;
            
            for(int i = 1;i <= N;i++){
                    for(int j = 1;j <= N;j++){
                        if(V[i,j] != NA && V[i,j] == G[i,j]){
                            ans--;
                        }
                        
                    }
            }

            Console.WriteLine(ans);
        }  
        
        
        
        //繰り返し2乗法
        static long RepeatSquaring(long N,long M = 1000000005,long mod = 1000000007){
            if(M == 0){
                return 1;
            }else if(M%2 == 0){
                long t = RepeatSquaring(N,(M/2),mod)%mod;
                return (t*t)%mod;
            }else{
                return ((N%mod)*RepeatSquaring(N,M-1,mod))%mod;
            }
            
            }
            
            
            
        static void Factorization(long n){
            long i = 2;
            long tmp = n;
            
            while(i*i <= n){
                if(tmp%i == 0){
                    if(Primes.ContainsKey(i)){
                        Primes[i]++;
                    }else{
                        Primes.Add(i,1);
                    }
                    tmp /= i;
                }else{
                    i++;
                }
            }
            
            if(tmp != 1){
                Primes.Add(tmp,1);
            }
            
            
        }
        
      
      
      
    }
  


    public class Node{
      public long loc = long.MinValue;
      public Dictionary<long,long> adj = new Dictionary<long,long>();
    }
  
  
    public class PriorityQueue<T> : IEnumerable<T>
    {
        private readonly List<T> _data = new List<T>();
        private readonly IComparer<T> _comparer;
        private readonly bool _isDescending;

        public PriorityQueue(IComparer<T> comparer, bool isDescending = true)
        {
            _comparer = comparer;
            _isDescending = isDescending;
        }

        public PriorityQueue(Comparison<T> comparison, bool isDescending = true)
            : this(Comparer<T>.Create(comparison), isDescending)
        {
        }

        public PriorityQueue(bool isDescending = true)
            : this(Comparer<T>.Default, isDescending)
        {
        }

        public void Enqueue(T item)
        {
            _data.Add(item);
            var childIndex = _data.Count - 1;
            while (childIndex > 0)
            {
                var parentIndex = (childIndex - 1) / 2;
                if (Compare(_data[childIndex], _data[parentIndex]) >= 0)
                    break;
                Swap(childIndex, parentIndex);
                childIndex = parentIndex;
            }
        }

        public T Dequeue()
        {
            var lastIndex = _data.Count - 1;
            var firstItem = _data[0];
            _data[0] = _data[lastIndex];
            _data.RemoveAt(lastIndex--);
            var parentIndex = 0;
            while (true)
            {
                var childIndex = parentIndex * 2 + 1;
                if (childIndex > lastIndex)
                    break;
                var rightChild = childIndex + 1;
                if (rightChild <= lastIndex && Compare(_data[rightChild], _data[childIndex]) < 0)
                    childIndex = rightChild;
                if (Compare(_data[parentIndex], _data[childIndex]) <= 0)
                    break;
                Swap(parentIndex, childIndex);
                parentIndex = childIndex;
            }
            return firstItem;
        }

        public T Peek()
        {
            return _data[0];
        }

        private void Swap(int a, int b)
        {
            var tmp = _data[a];
            _data[a] = _data[b];
            _data[b] = tmp;
        }

        private int Compare(T a, T b)
        {
            return _isDescending ? _comparer.Compare(b, a) : _comparer.Compare(a, b);
        }

        public int Count => _data.Count;

        public IEnumerator<T> GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
}