1 /*
2 题外话:
3 没想到这是一道最短路题
4 原来最短路可以这样变形,有时也可以多次利用最短路
5 求一个问题
6 思路:
7 我们从每个有藏宝的地方为起点 求到各个点的可以的最大
8 重量
9
10 我们相当于求出了从出口 到 一个藏宝点 所
11 允许的最大重量
12
13 把所有藏宝点的按重量 排序(从小到大)
14 先到最小的藏宝点带上 宝物 再去次大
15 一次类推
16 */
17 #include<iostream>
18 #include<cstdio>
19 #include<cstring>
20 #include<algorithm>
21 using namespace std;
22
23 const int size = 8001;
24 struct node
25 {
26 int e;
27 int v;
28 int next;
29 }edge[30001];
30 int k[size];
31 int en=0;
32
33 int qmin(int x,int y)
34 {
35 if(x<y)return x;
36 else return y;
37 }
38
39 int dij(int beg,int last,int N)
40 {
41 int i;
42 bool flag[size];
43 int d[size];
44 memset(flag,0,sizeof(flag));
45 memset(d,0,sizeof(d));
46 d[beg]=7777777;
47 flag[beg]=1;
48 while(beg!=last)
49 {
50 for(i=k[beg];i!=-1;i=edge[i].next)
51 {
52 int e = edge[i].e;
53 int v = edge[i].v;
54 if(!flag[e] && d[e]<qmin(d[beg],v))
55 d[e]=qmin(d[beg],v);
56 }
57 int tmax=0;
58 for(i=1;i<=N;++i)
59 if(!flag[i]&&d[i]>tmax)
60 {
61 tmax=d[i];
62 beg=i;
63 }
64 flag[beg]=1;
65 }
66 return d[last];
67 }
68
69 int main()
70 {
71 int N,M,K,W,i;
72 int x,y,z;
73 int kc[size];
74 int d[size];
75 while(~scanf("%d%d%d%d",&N,&M,&K,&W))
76 {
77 memset(k,-1,sizeof(k));
78 en=0;
79 for(i=1;i<=K;++i)
80 scanf("%d",&kc[i]);
81 for(i=0;i<M;++i)
82 {
83 scanf("%d%d%d",&x,&y,&z);
84
85 edge[en].e=y;
86 edge[en].v=z;
87 edge[en].next=k[x];
88 k[x]=en++;
89
90 edge[en].e=x;
91 edge[en].v=z;
92 edge[en].next=k[y];
93 k[y]=en++;
94 }
95 for(i=1;i<=K;++i)
96 d[i]=dij(kc[i],1,N);
97 sort(d+1,d+K+1);
98 int total=0;
99 for(i=1;i<=K;++i)
100 if(d[i]>=(total+1)*W)
101 total++;
102 printf("%d\n",total);
103 }
104 return 0;
105 }