问题描述
有一天,琪琪想拜访她的一位朋友。由于容易晕车,她想尽快赶到朋友家。现在给你一张城市的交通路线图,以及琪琪家附近的车站,让她可以乘坐。您可能认为 Kiki 可以在任何车站换车。请找出 Kiki 需要花费的最少时间。为方便起见,如果城市有 n 个公交车站,则车站将表示为整数 1,2,3…n。
输入
有几个测试用例。
每个case以n、m、s三个整数开头,(n<1000,m<20000,1=<s<=n) n代表本市公交站数,m代表之间有向路数公共汽车站。(也许两个公共汽车站之间有几种方式。) s 代表 Kiki 朋友家附近的公共汽车站。
然后跟随 m 行,每行包含三个整数 p , q , t (0<t<=1000)。意味着从站 p 到站 q 有一条路,它将花费 t 分钟。
然后有一个整数 w(0<w<n) 的行,表示 Kiki 在开始时可以采取的站数。然后后面的 w 个整数代表这些站。
输出
每个数据集的输出包含一行:Kiki 需要花费的最少时间,如果无法找到这样的路线,则输出“-1”。
样本输入
5 8 5
1 2 2
1 5 3
1 3 4
2 4 7
2 5 6
2 3 5
3 5 1
4 5 1
2
2 3
4 3 4
1 2 3
1 3 4
2 3 2
1
1
样本输出
1
-1
#include<bits/stdc++.h>
using namespace std;
#define inf 0x7FFFFFFF
int n, m, s, p, q, t, w;
int vis[1005], dis[1005], mp[1005][1005];
int main() {
while(~scanf("%d %d %d", &n, &m, &s)) {
memset(vis, 0, sizeof(vis));
for(int i = 0; i <= n; i++) { // 注意取等
dis[i] = inf;
for(int j = 0; j <= n; j++) mp[i][j] = inf; // 取等
}
for(int i = 0; i < m; i++) {
scanf("%d %d %d", &p, &q, &t);
mp[p][q] = min(mp[p][q], t);
}
scanf("%d", &w);
int a;
for(int i = 0; i < w; i++) {
scanf("%d", &a);
mp[0][a] = 0;
}
int st = 0, ed = s, minm, next;
dis[st] = 0;
while(st != ed) {
vis[st] = 1;
minm = inf;
for(int i = 0; i <= n; i++) {
if(mp[st][i] != inf)
dis[i] = min(mp[st][i] + dis[st], dis[i]);
if(!vis[i] && dis[i] < minm) {
minm = dis[i];
next = i;
}
}
if(minm == inf) break;
st = next;
}
printf("%d\n", dis[ed] == inf ? -1 : dis[ed]);
}
return 0;
}