首先把最短路计算出来.
然后把查询时间存下来.
再从终点开始BFS,如果dis[u] == dis[v] + w 说明点v在最短路上,那么就枚举查询,满足dis[u] > qtime[i] && dis[v] <qtime[i] 那么就说明小偷可以出现在这条路上,最后把小偷正好在点上的情况也枚举下.
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <map>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 1005;
int dis[maxn], head[maxn], qtime[maxn], ans[maxn] , n, m, s ,e, q;
bool vis[maxn], inPath[maxn],vis2[maxn][maxn];
struct edge{
int v, w, next;
}es[maxn * maxn];
struct node{
int u, v;
node(int uu = 0, int vv = 0)
:u(uu),v(vv){}
bool operator<(const node & rhs)const{
return v > rhs.v;
}
};
void bfs(){
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
memset(inPath,0,sizeof(inPath));
queue<int>que;
que.push(e);
vis[e] = 1;
inPath[e] = 1;
while (que.size()){
int u = que.front();
que.pop();
for (int ne = head[u]; ne != -1; ne = es[ne].next){
int v = es[ne].v, w = es[ne].w;
if(!vis2[v][u] && dis[u] == dis[v] + w){
inPath[v] = 1;
vis2[u][v] = vis2[v][u] = 1;
for (int i = 0; i < q; ++i){
if(dis[u] > qtime[i] && dis[v] < qtime[i]){
ans[i]++;
}
}
if(!vis[v]){
vis[v] = 1;
que.push(v);
}
}
}
}
for (int i = 1; i <= n; ++i){
if(inPath[i]){
for (int j = 0; j < q;++j){
if(dis[i] == qtime[j]){
ans[j]++;
}
}
}
}
}
inline void addEdge(int u, int v, int w, int eidx){
es[eidx].v = v;
es[eidx].w = w;
es[eidx].next = head[u];
head[u] = eidx;
}
void dijkstra(){
priority_queue<node>q;
q.push(s);
memset(vis,0,sizeof(vis));
memset(dis, 0X20, sizeof(dis));
dis[s] = 0;
while (q.size()){
node t = q.top();q.pop();
int u = t.u;
if(vis[u])continue;
vis[u] = 1;
for (int ne = head[u]; ne != -1; ne = es[ne].next){
int v = es[ne].v, w = es[ne].w;
if(dis[v] > dis[u] + w && !vis[v]){
dis[v] = dis[u] + w;
q.push(node(v,dis[v]));
}
}
}
}
int main(){
int cas = 0;
while (scanf("%d %d %d %d", &n, &m, &s, &e) == 4){
if(cas++)printf("\n");
memset(head, -1, sizeof(head));
int eidx = 0;
for (int i = 0; i < m; ++i){
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
addEdge(u, v, w, eidx++),addEdge(v, u, w, eidx++);
}
dijkstra();
scanf("%d", &q);
for (int i = 0; i < q; ++i){
scanf("%d", &qtime[i]);
}
memset(ans,0,sizeof(ans));
bfs();
for (int i = 0; i < q; ++i){
if(qtime[i] == 0 || qtime[i] >= dis[e])printf("1\n");
else printf("%d\n",ans[i]);
}
}
return 0;
}