注意要点:两点之间可能存在多边,我的模板中除了floyd都是处理不了多边的,但是floyd在这题显然是不够看的,直接超时。处理的办法就是舍弃存边的结构体edge,像floyd一样定义一个d[num][num]来存放两点间的坐车时间,输入时选取两点之间的最小时间即可。对于只有个别站能乘坐的问题,只要设该站到原点的时间为0,最后求目的地到原点的时间即可。
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int num = 1001;
int n, m, s, k;
int dis[num];
int done[num];
int d[num][num];
struct node{
int id, dist;
node(int u, int d){id=u;dist=d;}
bool operator <(const node &a)const
{ return dist > a.dist;}
};
void dijkstra(){
priority_queue<node>q;
q.push(node(0, 0));
while(!q.empty()){
node u = q.top();
q.pop();
if(done[u.id]) continue;
done[u.id] = 1;
for(int i=0; i<=n; i++){
if(done[i]) continue;
if(dis[i] > u.dist + d[u.id][i]){
dis[i] = u.dist + d[u.id][i];
q.push(node(i, dis[i]));
}
}
}
}
int main(){
while(~scanf("%d%d%d", &n, &m, &s)){
for(int i=0; i<=n; i++){
for(int j=0; j<=n; j++)
d[i][j] = inf;
dis[i] = inf;
done[i] = d[i][i] = 0;
}
while(m--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[a][b] = min(d[a][b], c);
}
scanf("%d", &k);
while(k--){
int a;
scanf("%d", &a);
d[0][a] = 0;
}
dijkstra();
if(dis[s]<inf) printf("%d\n", dis[s]);
else printf("-1\n");
}
return 0;
}