错了最后一个点,最后看题解发现最后统计条数的时候不能直接在队列中存储类型(最短路 or 次短路)从而更新条数。而是应该在取出队列时通过序号和距离来判断该条路的类型。如果距离得不到匹配则 continue 。
可为什么这样就是对的呢?(为什么我那样是错的)。如果此时的距离不是对应的最短路或次短路,那么在判断的时候不应该就不会更新其他的点(因为其他点会被更短的更新),也不会对结果产生影响吗?QAQ
本人代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int T,n,m,S,F;
int dist[1005][2],num[1005][2];
int head[1005],nex[10005],to[10005],val[10005],cnt;
void add(int x,int y,int z){
nex[++cnt]=head[x],head[x]=cnt,to[cnt]=y,val[cnt]=z;
}
struct node{int number,w,type;};
bool operator <(const node &a,const node &b){
return a.w>b.w;
}
priority_queue<node> q;
void dij(){
//0 表示最短路,1 表示次短路
//dist 是距离,num 是路径条数计数
memset(dist,0x7f,sizeof(dist));
memset(num,0,sizeof(num));
num[S][0]=1;
dist[S][0]=0;
q.push((node){S,0,0});
while(!q.empty()){
node x=q.top();
q.pop();
for(int i=head[x.number];i;i=nex[i]){
int y=to[i];
if(dist[y][0]>x.w+val[i]){
dist[y][1]=dist[y][0];
num[y][1]=num[y][0];
dist[y][0]=x.w+val[i];
num[y][0]=num[x.number][x.type];
q.push((node){y,dist[y][0],0});
}
else if(dist[y][0]==x.w+val[i]){
num[y][0]+=num[x.number][x.type];
//cout<<"0 "<<y<<" "<<dist[y][0]<<" "<<num[y][0]<<endl;
//q.push((node){y,dist[y][0],num[y][0]});
}
else if(dist[y][1]>x.w+val[i]){
dist[y][1]=x.w+val[i];
num[y][1]=num[x.number][x.type];
q.push((node){y,dist[y][1],1});
}
else if(dist[y][1]==x.w+val[i]){
num[y][1]+=num[x.number][x.type];
// cout<<"1 "<<y<<" "<<dist[y][1]<<" "<<num[y][1]<<endl;
}
}
}
int ans=num[F][0];
if(dist[F][1]==dist[F][0]+1) ans+=num[F][1];
cout<<ans<<endl;
}
int main(){
scanf("%d",&T);
while(T--){
memset(head,0,sizeof(head));
memset(nex,0,sizeof(nex));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y,l;
scanf("%d%d%d",&x,&y,&l);
add(x,y,l);
}
scanf("%d%d",&S,&F);
dij();
}
}