#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FOR(a,b,c) for(int a=b;a<=c;a++) #define SIZEOF(a) (sizeof(a)/sizeof(a[0])) #define FORARR(i,a) for(unsigned i=0; i adj[10001]; bool alive[10001]; int killDist[10001]; struct item { int town; int dist; item(int t, int d) : town(t), dist(d) {} }; bool operator<(const item &one, const item &two) { return one.dist > two.dist; } int main(void) { while (GETI(N) == 1 && N > 0) { GETI(M); GETI(A); GETI(K); FORARR(i, adj) adj[i] = list(); FOR(i,0,M-1) { int from, to, w; GETI(from); GETI(to); GETI(w); adj[from].push_back(edge(to, w)); adj[to].push_back(edge(from, w)); } int alive_cnt = N; FORARR(i, killDist) killDist[i] = -1; FORARR(i, alive) alive[i] = true; FOR(i, 1, A) { int base; GETI(base); // optimalizace - vsichni jsou uz stejne mrtvi if (alive_cnt == 0) { cout << 0 << endl; continue; } // z base se sirime do vzdalenosti K priority_queue pq; bool visited[10001] = {0}; pq.push(item(base, 0)); while (!pq.empty()) { item it = pq.top(); pq.pop(); if (visited[it.town]) continue; if (alive[it.town]) { alive[it.town] = false; alive_cnt--; } FOREACH(nb, adj[it.town]) { if (visited[nb->to]) continue; int d = it.dist + nb->weight; if (d >= K) continue; // zabijim mesto nb->to // optimalizace if (killDist[nb->to] != -1 && d >= killDist[nb->to]) continue; killDist[nb->to] = d; pq.push(item(nb->to, d)); } visited[it.town] = true; } cout << alive_cnt << endl; } cout << endl; } return 0; }