求最短路,和最短路长度加1的路的条数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N = 1009;
const int M = 10009;
const int INF =0x3f3f3f3f;
int n,m,dis[N<<1],cnt[N<<1],ST,EN;
bool visit[N<<1];
struct node
{
int to,nex,dis;
} L[M];
int F[N],cntF;
void add(int f,int t,int dis)
{
L[cntF].dis = dis;
L[cntF].nex = F[f];
L[cntF].to = t;
F[f] = cntF++;
}
void init()
{
scanf("%d%d",&n,&m);
memset(cnt,0,sizeof(cnt));
memset(F,0,sizeof(F));
cntF = 1;
int f,t,dis;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&f,&t,&dis);
add(f,t,dis);
}
scanf("%d%d",&ST,&EN);
}
struct nod
{
int dis,to;
bool operator<(const nod t) const
{
return dis>t.dis;
}
};
priority_queue<nod> que;
void solve()
{
while(!que.empty()) que.pop();
memset(visit,false,sizeof(visit));
memset(dis,INF,sizeof(dis));
nod e,t;
e.to = ST;
e.dis = 0;
que.push(e);
dis[ST] = 0;
cnt[ST] = 1;
cnt[ST+N] = 1;
while(!que.empty())
{
e =que.top();
que.pop();
if(visit[e.to]) continue;
visit[e.to] = true;
for(int i=F[(e.to>N?e.to-N:e.to)]; i; i=L[i].nex)
{
int to = L[i].to;
int tmp=dis[e.to]+L[i].dis;
if(dis[to]>tmp)
{
if(dis[to]!=INF)
{
dis[to+N] = dis[to];
cnt[to+N] = cnt[to];
t.dis=dis[to+N];
t.to=to+N;
que.push(t);
}
dis[to] = tmp;
cnt[to] = cnt[e.to];
t.dis = dis[to];
t.to = to;
que.push(t);
}
else if(dis[to] == tmp)
{
cnt[to] += cnt[e.to];
}
else if(dis[to+N] > tmp)
{
dis[to+N] = tmp;
cnt[to+N] = cnt[e.to];
t.dis = dis[to+N];
t.to = to+N;
que.push(t);
}
else if(dis[to+N] == tmp)
{
cnt[to+N] += cnt[e.to];
}
}
}
printf("%d\n",cnt[EN]+(dis[EN+N]-dis[EN]==1?cnt[EN+N]:0));
}
int main()
{
freopen("in.txt","r",stdin);
int cas;
scanf("%d",&cas);
while(cas--)
{
init();
solve();
}
return 0;
}