Problem:
イクタ君は、無向グラフについて異常なほどの思い入れを持っている。イクタ君は、無向グラフ G とその 2 点 s,tの組(G,s,t)のうち、その「うつくしさ」が大きいものが好きである。
組(G,s,t)の「うつくしさ」とは、辺 e = \{u, v\} (u と v は G の異なる 2 点) で、Gにおけるsからtへの最短路の長さが、Gにeをつけくわえた無向グラフにおけるsからtへの最短路の長さより 1 だけ大きいものの個数である。

あなたの仕事は、組(G,s,t)が与えられたとき、その「うつくしさ」を求めるプログラムを書くことである。

Input

入力は以下の形式で与えられる。

N M s t
x1 y1
...
xi yi
...
xM yM

最初に無向グラフの頂点数、辺数、2つの頂点を表す整数N,M,s,tが入力される。
2行目からM+1行目までは辺によって結ばれている2つの頂点が入力される。
(ただし、G の頂点集合を\{1,..., N\}とする。)

Constraints

入力中の各変数は以下の制約を満たす。

2≤ N ≤ 100,000

1≤ M ≤ 300,000

1≤ s,t,xi,yi ≤ N

s と t とは異なる

s から t に辿り着けることは保証されている

Output

与えられたグラフをGとしたとき、組(G,s,t)の「うつくしさ」を1行で出力せよ。

Sample Input 1

3 2 1 3
1 2
2 3

Output for the Sample Input 1

1

頂点1から頂点3に辺を張ると、2点間の最短距離が 1 短くなる。

Sample Input 2

9 8 7 8
2 6
4 9
8 6
9 2
3 8
1 8
8 5
7 9

Output for the Sample Input 2

7

Sample Input 3

4 3 1 4
1 2
3 4
4 1

Output for the Sample Input 3

0

頂点1と頂点4には既に辺が張られているので、これ以上距離を縮めることはできない。

Sample Input 4

9 7 8 9
9 6
6 5
3 6
3 7
2 5
8 5
1 4

Output for the Sample Input 4

2

Solution in C (judge verdict: Wrong Answer)

// AOJ 2608: Minus One
// 2017.11.30 bal4u@uu

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 300000
typedef struct { int t, node; } QUE;
QUE que[MAX]; int qsize;

#define PARENT(i) ((i)>>1)
#define LEFT(i)   ((i)<<1)
#define RIGHT(i)  (((i)<<1)+1)

void min_heapify(int i)
{
	int l, r, min;
	QUE qt;

	l = LEFT(i), r = RIGHT(i);
	if (l < qsize && que[l].t < que[i].t) min = l; else min = i;
	if (r < qsize && que[r].t < que[min].t) min = r;
	if (min != i) {
		qt = que[i], que[i] = que[min], que[min] = qt;
		min_heapify(min);
	}
}

void deq()
{
//	if (qsize == 0) return 0;
//	*n = que[0].node, *t = que[0].t, *c = que[0].c;
	que[0] = que[--qsize];
	min_heapify(0);
//	return 1;
}

void enq(int n, int t)
{
	int i, min;
	QUE qt;

	i = qsize++;
	que[i].node = n, que[i].t = t;
	while (i > 0 && que[min = PARENT(i)].t > que[i].t) {
		qt = que[i], que[i] = que[min], que[min] = qt;
		i = min;
	}
}

typedef struct { int *to; } TBL;
TBL *tbl; int len[100001];
int x[100001], y[100001];
int smin[100001], tmin[100001];
int scnt[100001], tcnt[100001];

void dijkstra(int *node, int start)
{
	int i, s, e, d;

	qsize = 0;
	node[start] = 0;
	enq(start, 0);
	while (qsize) {
		s = que[0].node; deq();
		for (i = 0; i < len[s]; i++) {
			e = tbl[s].to[i];
			d = node[s] + 1;
			if (d < node[e]) node[e] = d, enq(e, d);
		}
	}
}

char buf[40], *p;
int getint()
{
	int n = 0;
	while (*p >= '0') n = (n<<3) + (n<<1) + (*p++ & 0xf);
	return n;
}

int main()
{
	int n, m, s, t, i;
	long long ans;

	fgets(p=buf, 40, stdin);
	n = getint(), p++, m = getint(), p++, s = getint()-1, p++, t = getint()-1;
	for (i = 0; i < m; i++) {
		fgets(p=buf, 20, stdin);
		x[i] = getint()-1, p++, y[i] = getint()-1;
		len[x[i]]++, len[y[i]]++;
	}
	tbl = calloc(n+2, sizeof(TBL));
	for (i = 0; i < n; i++) tbl[i].to = calloc(len[i]+2, sizeof(int));
	memset(len, 0, sizeof(len));
	for (i = 0; i < m; i++) {
		tbl[x[i]].to[len[x[i]]++] = y[i];
		tbl[y[i]].to[len[y[i]]++] = x[i];
	}

	memset(smin, 0x33, sizeof(smin));
	dijkstra(smin, s);
	memset(tmin, 0x33, sizeof(tmin));
	dijkstra(tmin, t);

	for (i = 0; i < n; i++) {
		if (smin[i] < n) scnt[smin[i]]++;
		if (tmin[i] < n) tcnt[tmin[i]]++;
	}

	ans = 0, s = smin[t]-1;
	for (i = 0; i < s; i++) ans += (long long)scnt[i] * tcnt[s-1-i];
	printf("%lld\n", ans);
	return 0;
}