![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//两遍spfa,第一遍找最短路,第二遍统计i到j的道路个数 //根据乘法计数原理乘起来即可 #include<cstdio> #include<queue> #define MAX 100001 #define mod 2147483647 #define ll long long #define M 499500 using namespace std; queue<int> d; int n,m,x,y,z,dist[1002],f[1002]; ll g[1001]={0ll},ans=1ll; int be[1001],next[M*2],to[M*2],hf[M*2],cnt=0; void add(int x,int y,int z){ cnt++; next[cnt]=be[x]; be[x]=cnt; to[cnt]=y; hf[cnt]=z; } void spfa(){ for(int i=1;i<=n;i++) dist[i]=MAX; dist[1]=0; d.push(1); while(!d.empty()){ int zz=d.front(); f[zz]=0; d.pop(); for(int i=be[zz];i;i=next[i]) if(hf[i]+dist[zz]<dist[to[i]]){ dist[to[i]]=hf[i]+dist[zz]; if(!f[to[i]]){ f[to[i]]=1; d.push(to[i]); } } } } void spfa2(){ d.push(1); while(!d.empty()){ int xz=d.front(); d.pop(); for(int i=be[xz];i;i=next[i]) if(hf[i]+dist[xz]==dist[to[i]]){ g[to[i]]++; if(g[to[i]]>=mod) g[to[i]]-=mod; if(!f[to[i]]){ d.push(to[i]); f[to[i]]=1; } } } for(int i=1;i<=n;i++){ ans=ans*g[i]; if(ans>=mod) ans%=mod; } } int main(){ freopen("castle.in","r",stdin); freopen("castle.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } spfa(); g[1]=1ll; spfa2(); printf("%I64d ",ans); fclose(stdin); fclose(stdout); return 0; }