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.Globalization;
﻿﻿﻿﻿﻿using System.IO;
﻿﻿﻿﻿﻿using System.Linq;

namespace CF317
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var sr = new InputReader(Console.In);
            //var sr = new InputReader(new StreamReader("input.txt"));
            var task = new Task();
            using (var sw = Console.Out)
            //using (var sw = new StreamWriter("output.txt"))
            {
                task.Solve(sr, sw);
                //Console.ReadKey();
            }
        }
    }

    internal class Task
    {
        public void Solve(InputReader sr, TextWriter sw)
        {
            var input = sr.ReadArray(Int32.Parse);
            var n = input[0];
            var m = input[1];
            var graph = new Graph(n);
            for (var i = 0; i < m; i++) {
                input = sr.ReadArray(Int32.Parse);
                graph.Insert(input[0] - 1, input[1] - 1, input[2]);
            }

            sw.Write(graph.AllPairsShortestPath());
        }
    }

    class Graph
    {
        private int[,] matrix;
        private readonly int n;

        public Graph(int n)
        {
            matrix = new int[n, n];
            this.n = n;
        }

        public void Insert(int x, int y, int c)
        {
            matrix[x, y] = c;
            matrix[y, x] = c;
        }

        public int AllPairsShortestPath()
        {
            const long Max = (long) 1e15;
            var distances = new long[n, n];
            var parents = new int[n, n];
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < n; j++)
                {
                    parents[i, j] = -1;
                }
            }
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (i == j) {
                        distances[i, j] = 0;
                    }
                    else {
                        if (matrix[i, j] == 0) {
                            distances[i, j] = Max;
                        }
                        else {
                            distances[i, j] = matrix[i, j];
                        }
                    }
                }
            }
            for (var k = 0; k < n; k++) {
                for (var i = 0; i < n; i++) {
                    for (var j = 0; j < n; j++) {
                        if (distances[i, j] > distances[i, k] + distances[k, j]) {
                            distances[i, j] = distances[i, k] + distances[k, j];
                            parents[i, j] = k;
                        }
                    }
                }
            }
            var inPaths = new bool[n, n];
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (i == j) {
                        inPaths[i, j] = true;
                    }
                }
            }
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    var p = parents[i, j];
                    if (p == -1 && matrix[i, j] != 0) {
                        inPaths[i, j] = true;
                        inPaths[j, i] = true;
                    }
                    else {
                        var prev = j;
                        while (p != -1) {
                            inPaths[prev, p] = true;
                            inPaths[p, prev] = true;
                            prev = p;
                            p = parents[i, p];
                        }
                        inPaths[i, prev] = true;
                        inPaths[prev, i] = true;
                    }
                }
            }
            var count = 0;
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (matrix[i, j] != 0) {
                        if (!inPaths[i, j]) {
                            count++;
                            inPaths[j, i] = true;
                        }
                    }
                }
            }

            return count;
        }
    }
}

internal class InputReader : IDisposable
{
    private bool isDispose;
    private readonly TextReader sr;

    public InputReader(TextReader stream)
    {
        sr = stream;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public string NextString()
    {
        var result = sr.ReadLine();
        return result;
    }

    public int NextInt32()
    {
        return Int32.Parse(NextString());
    }

    public long NextInt64()
    {
        return Int64.Parse(NextString());
    }

    public string[] NextSplitStrings()
    {
        return NextString()
            .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public T[] ReadArray<T>(Func<string, CultureInfo, T> func)
    {
        return NextSplitStrings()
            .Select(s => func(s, CultureInfo.InvariantCulture))
            .ToArray();
    }

    public T[] ReadArrayFromString<T>(Func<string, CultureInfo, T> func, string str)
    {
        return
            str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => func(s, CultureInfo.InvariantCulture))
                .ToArray();
    }

    protected void Dispose(bool dispose)
    {
        if (!isDispose)
        {
            if (dispose)
                sr.Close();
            isDispose = true;
        }
    }

    ~InputReader()
    {
        Dispose(false);
    }
}