最近才听说次短路问题,以为挺简单其实是眼高手低,
题目意思就是裸的次短路,问最短路的个数和与最短路差1的个数和,考虑dijkstra的特性,可以利用每次进队列的方式方式实现。
朴素的dij就是进dis数列中的最小的,还要标记vis,那么次短路可以看做分类讨论
首先开出最短路和次短路的dis,cnt,和vis,那么入队方式什么的都和朴素的一样,
但是注意分类讨论,
如果拿出来的是个最短路,就分情况看看是不是影响最短路,如果影响最短路,那么次短路也相应转移,所以把两个都入,
如果不影响最短路,再判断是不是影响次短路,同理。
如果拿出来的是个次短路,就分情况看看是不是影响次短路,同理。
如果说dij是,似乎有些dp思想。。。
太弱了,最近还习惯性手残。。。。继续努力。。。加油
#include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cstring>
#include <math.h>
using namespace std;
const int maxn=100005;
int n,m,x,y;
int dis[maxn][2];
int cnt[maxn][2];
int vis[maxn][2];
struct edge{
int x,val;
edge(int a,int c):x(a),val(c){};
};
struct node{
int x,y,val;
node(int a,int b,int c):x(a),y(b),val(c){};
};
bool operator <(const node e1,const node e2){
return e1.val>e2.val;
}
vector<edge> v[maxn];
void dij(int x,int y){
for(int i=0;i<=n;i++)
dis[i][0]=dis[i][1]=1<<30;
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
priority_queue<node> pq;
dis[x][0]=0;
cnt[x][0]=1;
pq.push(node(x,0,0));
while(!pq.empty()){
node cs=pq.top();
pq.pop();
if(vis[cs.x][cs.y])continue;
vis[cs.x][cs.y]=1;
for(int i=0;i<v[cs.x].size();i++){
if(cs.y==0){
if(dis[cs.x][0]+v[cs.x][i].val<=dis[v[cs.x][i].x][0]){
if(dis[cs.x][0]+v[cs.x][i].val==dis[v[cs.x][i].x][0]){
cnt[v[cs.x][i].x][0]+=cnt[cs.x][0];
}
else{
cnt[v[cs.x][i].x][1]=cnt[v[cs.x][i].x][0];
cnt[v[cs.x][i].x][0]=cnt[cs.x][0];
dis[v[cs.x][i].x][1]=dis[v[cs.x][i].x][0];
pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
}
dis[v[cs.x][i].x][0]=dis[cs.x][0]+v[cs.x][i].val;
pq.push(node(v[cs.x][i].x,0,dis[v[cs.x][i].x][0]));
}
else if(dis[cs.x][0]+v[cs.x][i].val<=dis[v[cs.x][i].x][1]){
if(dis[cs.x][0]+v[cs.x][i].val==dis[v[cs.x][i].x][1]) cnt[v[cs.x][i].x][1]+=cnt[cs.x][0];
else cnt[v[cs.x][i].x][1]=cnt[cs.x][0];
dis[v[cs.x][i].x][1]=dis[cs.x][0]+v[cs.x][i].val;
pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
}
}
else{
if(dis[cs.x][1]+v[cs.x][i].val<=dis[v[cs.x][i].x][1]){
if(dis[cs.x][1]+v[cs.x][i].val==dis[v[cs.x][i].x][1])cnt[v[cs.x][i].x][1]+=cnt[cs.x][1];
else cnt[v[cs.x][i].x][1]=cnt[cs.x][1];
dis[v[cs.x][i].x][1]=dis[cs.x][1]+v[cs.x][i].val;
pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
}
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
int a,b,c;
for(int i=0;i<=n;i++)
v[i].clear();
for(int i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
v[a].push_back(edge(b,c));
}
scanf("%d%d",&x,&y);
dij(x,y);
if(dis[y][0]+1==dis[y][1])
cout<<cnt[y][1]+cnt[y][0]<<endl;
else
cout<<cnt[y][0]<<endl;
}
return 0;
}