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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

//ダイクストラ法

#include <bits/stdc++.h>
#define max 10000

using namespace std;

struct edge{
	int cost;
	int to;
	int from;
};


struct p_que{
	int heap[max][2];
	int now;
};
struct p_que* make();
void push(p_que *p, int num,int index);
int smal(p_que *p,int p_id);
int pop(p_que *p);


void dainyu(edge miti[],int a[],int b[],int c[],int m);
int d_stra(int w,int cost[],edge miti[],int edge_num,int node_num,p_que *pq);

int main(void)
{
	int n,m; cin>>n>>m;
	int a[m],b[m],c[m]; for(int i = 0; i < m; i++) cin>>a[i]>>b[i]>>c[i];
	int edge_num = m;
	int node_num = n;
	struct edge miti[edge_num];
	dainyu(miti,a,b,c,m);
	
	int ans = 0;
	for(int j = 0; j < m; j++){
		p_que *pq; pq = make();
		int cost[node_num]; for(int i = 0; i< node_num; i++) cost[i] = max;
		int start_node = a[j]-1;
		cost[start_node] = 0;
		int w = start_node;
		for(int i = 0; i< node_num; i++){
			w = d_stra(w,cost,miti,edge_num,node_num,pq);
		}
		if(cost[b[j]-1] < c[j]){
			ans++;
		}
		/*
		cout<<"j = "<<j<<", start_node = "<<start_node<<endl;
		for(int i = 0; i < n; i++){
			cout<<"cost[i] = "<<cost[i];
			cout<<", ";
		}
		cout<<"\n"<<endl;
		*/
	}
	/*
	for(int i = 0; i <m; i++){
		cout<<"miti[i].from = "<<miti[i].from<<", miti[i].to = "<<miti[i].to<<", miti[i].cost = "<<miti[i].cost<<endl;
	}
	*/
	cout<<ans<<endl;
	return 0;
}


void dainyu(edge miti[],int a[],int b[],int c[], int m)
{
	for(int i = 0; i < m; i++){
		miti[i].from = a[i]-1; 
		miti[i].to = b[i]-1;
		miti[i].cost = c[i];
	}
}

int d_stra(int w,int cost[],edge miti[],int edge_num,int node_num, p_que *pq)
{
	for(int i = 0; i < edge_num; i++){
		if(w == miti[i].to){
			if(cost[w]+miti[i].cost < cost[miti[i].from]){
				push(pq,cost[w]+miti[i].cost,miti[i].from);
				cost[miti[i].from] = cost[w]+miti[i].cost;
			}
		}
		if(w == miti[i].from){
			if(cost[w]+miti[i].cost < cost[miti[i].to]){
				push(pq,cost[w]+miti[i].cost,miti[i].to);
				cost[miti[i].to] = cost[w]+miti[i].cost;
			}
		}
	}
	int re;
	re = pop(pq);
	return re;
}




struct p_que* make(){
	struct p_que *re;
	re = (struct p_que*)malloc(sizeof(struct p_que));
	if(re == NULL){
		cout<<"Eroor"<<endl;
		return 0;
	}
	else {
		re->now = 0;
		for(int i=0; i < max; i++){
			re->heap[i][1] = max;
			re->heap[i][0] = 0;
		}
		return re;
	}
}

void push(p_que *p,int num,int index){
	int tmp = 0;
	int c_id = p->now;
	p->heap[c_id][1]= num;
	p->heap[c_id][0]=index;
	while(p->heap[(c_id-1)/2][1] > p->heap[c_id][1]){
		tmp = p->heap[(c_id-1)/2][1]; p->heap[(c_id-1)/2][1] = num; p->heap[c_id][1] = tmp;
		tmp = p->heap[(c_id-1)/2][0]; p->heap[(c_id-1)/2][0] = index; p->heap[c_id][0] = tmp;
		c_id = (c_id-1)/2;
		if(c_id == 0) break;
	}
	p->now++;
}

int smal(p_que *p,int p_id){
	if(p->heap[p_id*2+2][1] < p->heap[p_id*2+1][1]) return p_id*2+2;
	else return p_id*2+1;
}

int pop(p_que *p){
	if(p->now == 0) return -1;
	int tmp,min,p_id = 0, re = p->heap[0][0];
	p->now--;
	p->heap[0][1] = p->heap[p->now][1];
	while(p->now > p_id*2+1){
		if(p->now > p_id*2+2) min = smal(p,p_id);
		else min = p_id*2+1;
		if(p->heap[min][1] < p->heap[p_id][1]){
			tmp = p->heap[min][1]; p->heap[min][1] = p->heap[p_id][1]; p->heap[p_id][1] = tmp;
			tmp = p->heap[min][0]; p->heap[min][0] = p->heap[p_id][0]; p->heap[p_id][0] = tmp;
			p_id = min;
		}
		else break;
	}
	return re;
}