考场想到了的,但是细节挂了
woj上lj数据跑spfa都可以过。。。。
注意在最短路计数的时候必须记visit,否则会重复访问一条边
dijkstra最短路也最好记一个(否则复杂度是错的)
主要是方案是一条边左右乘起来的平方(进去出去都要乘,两个人)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mk make_pair
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
const int N=100005;
const int M=400005;
const ll mod=1000000007;
int adj[N],nxt[M],str,des,to[M],n,m,cnt;
bool vis[N];
ll num[2][N],val[M],dis[2][N],maxn,ans;
inline void addedge(int u,int v,int w){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w;
nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,val[cnt]=w;
}
struct edge{
int u,v;
ll w;
}e[N<<1];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;
void spfa(int fir,int k)
{
memset(vis,0,sizeof(vis));
int x,y,i;num[k][fir]=1;
dis[k][fir]=0;q.push(make_pair(0,fir));
while(!q.empty())
{
x=q.top().second;q.pop();
if(vis[x])continue;vis[x]=true;
for(i=adj[x];i;i=nxt[i])
{
y=to[i];
if(dis[k][y]>dis[k][x]+val[i])
{
num[k][y]=num[k][x];
dis[k][y]=dis[k][x]+val[i];
q.push(make_pair(dis[k][y],y));
}
else if(dis[k][y]==dis[k][x]+val[i])
num[k][y]=(num[k][y]+num[k][x])%mod;
}
}
}
int main(){
// freopen("lx.cpp","r",stdin);
n=read(),m=read();
str=read(),des=read();
for(int i=1;i<=m;++i){
int u=read(),v=read(),w=read();
e[i].u=u,e[i].v=v,e[i].w=w;
addedge(u,v,w);
}
memset(dis,127,sizeof(dis));
spfa(str,0);
spfa(des,1);
maxn=dis[0][des];
for(int i=1;i<=m;++i){
if((dis[0][e[i].u]+dis[1][e[i].v]+e[i].w)==maxn){
if(abs(dis[0][e[i].u]-dis[1][e[i].v])<e[i].w){
ans+=(num[0][e[i].u]*num[1][e[i].v])%mod*(num[0][e[i].u]*num[1][e[i].v])%mod,ans%=mod;
}
}
if((dis[1][e[i].u]+dis[0][e[i].v]+e[i].w)==maxn){
if(abs(dis[1][e[i].u]-dis[0][e[i].v])<e[i].w){
ans+=(num[0][e[i].v]*num[1][e[i].u])%mod*(num[0][e[i].v]*num[1][e[i].u])%mod,ans%=mod;
}
}
}
for(int i=1;i<=n;++i){
if((dis[0][i]+dis[1][i])==maxn){
if(dis[0][i]==dis[1][i]){
ans+=(num[0][i]*num[1][i])%mod*(num[0][i]*num[1][i])%mod,ans%=mod;
}
}
}
cout<<(((num[0][des]*num[1][str])%mod-ans+mod)%mod)<<'\n';
}