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: Accepted)

#include<stdio.h>
int lub(int l,int r,int n,int *d){
  int m=(l+r)/2;
  if(l==r)return m;
  return n<=d[m]?lub(l,m,n,d):lub(m+1,r,n,d);
}
int ub(int l,int r,int n,int *d){
  int m=(l+r)/2;
  if(l==r)return m;
  return n<d[m]?ub(l,m,n,d):ub(m+1,r,n,d);
}
void prls(int v,int *ta,int *to,int *nt){
  int i,j;
  for(i=1;i<=v;i++){
    printf("%d:",i);
    for(j=ta[i];j+1;j=nt[j])printf("%d ",to[j]);
    printf("\n");
  }
  printf("\n");
}
  int n,m,s,g,r,t,a,b,l,ta[100010],to[600010],nt[600010],q[600010];
int main(){
  int c[2][100010]={};
  int i,f[100010]={};
  long long ans=0;
  scanf("%d %d %d %d",&n,&m,&s,&g);
  for(i=0;i<n;i++)ta[i+1]=-1;
  for(i=0;i<m;i++){
    scanf("%d %d",&a,&b);
    nt[i  ]=ta[to[i+m]=a];
    nt[i+m]=ta[to[i  ]=b];
    ta[a]=i  ;
    ta[b]=i+m;
  }
  q[t=0]=s;
  c[0][0]=0;
  f[s]=1;
  for(r=1;r-t;t++){
    if(q[t]==g)l=c[0][t];//printf("%d %d\n",q[t],c[0][q[t]]);
    for(i=ta[q[t]];i+1;i=nt[i]){//printf("%d ",c[0][q[t]]);
      if(f[to[i]])continue;//printf("%d ",c[0][q[t]]);
      c[0][r]=c[0][t]+1;//printf(":%d %d %d\n",q[t],c[0][r],to[i]);
      f[to[i]]=1;
      q[r++]=to[i];
    }
  }//printf("\n");
  m=r;//printf("%d %d\n",r,l);
  //for(i=0;i<r;i++)printf("%d ",c[0][i]);printf("\n");
  q[t=0]=g;
  f[g]=2;
  for(r=1;r-t;t++){
    ans+=ub(0,m-1,l-2-c[1][t],c[0])-lub(0,m-1,l-2-c[1][t],c[0]);
    //printf("%d %d %d\n",a,c[1][t],q[t]);
    for(i=ta[q[t]];i+1;i=nt[i]){
      if(f[to[i]]-1)continue;
      c[1][r]=c[1][t]+1;
      f[to[i]]=2;
      q[r++]=to[i];
    }
  }
  printf("%lld\n",ans);
  return 0;
}