思路:问最短路和次短路的条数和,并且次短路只比最短路多1,我们在dijkstra时进行统计和更新,用dis[i][0]表示到i点的最短距离用dis[i][1]表示到i点的次短距离,用cnt[i][0]表示到i的最短路径的条数,用cnt[i][1]表示到i的次短路径条数,当我们到 i 点最短路需要更新时,那么原来到 i 的最短路就会变成次短路,先更新一下次短路的距离,此时到 i 次短路的条数也是就变成了之前到 i 的最短路条数,然后我们再更新最短路的距离,最短路的次数也更新,当我们发现和最短路距离相同则我们发现新的路径,只更新到该点的最短路条数,当我们发现此时可以更新次短路距离时,更新次短路距离和路径条数,当发现和次短路距离相同时则只更新次短路条数,
代码:
#pragma GCC optimize(2)#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;#define SIS std::ios::sync_with_stdio(false)#define space putchar(' ')#define enter putchar('\n')#define lson root<<1#define rson root<<1|1typedef pair<int,int> PII;typedef pair<int,PII> PIII;constint mod=100003;constint N=2e5+5;constint inf=0x7f7f7f7f;intgcd(int a,int b){
return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){
return a*(b/gcd(a,b));}template<classT>voidread(T &x){
char c;bool op =0;while(c =getchar(), c <'0'|| c >'9')if(c =='-')
op =1;
x = c -'0';while(c =getchar(), c >='0'&& c <='9')
x = x *10+ c -'0';if(op)
x =-x;}template<classT>voidwrite(T x){
if(x <0)
x =-x,putchar('-');if(x >=10)write(x /10);putchar('0'+ x %10);}
ll qsm(int a,int b,int p){
ll res=1%p;while(b){
if(b&1)
res=res*a%p;
a=1ll*a*a%p;
b>>=1;}return res;}struct node
{
int to,nex,w;}edge[N];struct Ver
{
int ver,type,dist;booloperator>(const Ver &W)const{
return dist>W.dist;}};int head[N],dis[N][2],cnt[N][2];int tot,bcnt;int n,m,S,T;int vis[N][2];voidadd(int u,int v,int w){
edge[tot].to=v;
edge[tot].w=w;
edge[tot].nex=head[u];
head[u]=tot++;}intdij(){
memset(vis,0,sizeof vis);memset(cnt,0,sizeof cnt);memset(dis,inf,sizeof dis);
cnt[S][0]=1;
dis[S][0]=0;
priority_queue<Ver,vector<Ver>,greater<Ver>> heap;
heap.push({
S,0,0});while(heap.size()){
Ver now=heap.top();heap.pop();int distance=now.dist,type=now.type,ver=now.ver;int num=cnt[ver][type];if(vis[ver][type])continue;
vis[ver][type]=1;for(int i=head[ver];~i;i=edge[i].nex){
int v=edge[i].to,w=edge[i].w;if(dis[v][0]>distance+w){
dis[v][1]=dis[v][0];
cnt[v][1]=cnt[v][0];
heap.push({
v,1,dis[v][1]});
dis[v][0]=distance+w;
cnt[v][0]=num;
heap.push({
v,0,dis[v][0]});}elseif(dis[v][0]==distance+w){
cnt[v][0]+=num;}elseif(dis[v][1]>distance+w){
dis[v][1]=distance+w;
cnt[v][1]=num;
heap.push({
v,1,dis[v][1]});}elseif(dis[v][1]==distance+w){
cnt[v][1]+=num;}}}int res=cnt[T][0];if(dis[T][0]+1==dis[T][1])res+=cnt[T][1];return res;}intmain(){
int t;scanf("%d",&t);while(t--){
scanf("%d%d",&n,&m);memset(head,-1,sizeof head);while(m--){
int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}scanf("%d%d",&S,&T);printf("%d\n",dij());}return0;}