inlinevoidadd_edge(int x, int y, int z){ To1[++e1] = y; Next1[e1] = Begin1[x]; Begin1[x] = e1; W1[e1] = z; }
inlinevoidwork(int S) { static priority_queue <node> Q; for (int i = 1; i <= N; ++i) Dis[i] = inf, Vis[i] = 0; Dis[S] = 0; Q.push((node){S, 0}); while (!Q.empty()) { int x = Q.top().a; Q.pop(); if (Vis[x]) continue; Vis[x] = 1; for (int i = Begin1[x]; i; i = Next1[i]) { int y = To1[i]; if (Chkmin(Dis[y], Dis[x] + W[i])) Q.push((node){y, Dis[y]}); } } } }
inlineintdfs(int x, int k) { // cout<<x<<" "<<k<<endl; if (In[x][k]) return-1; if (Dp[x][k]) return Dp[x][k]; In[x][k] = 1; if (x == N) Dp[x][k] = 1; for (int i = Begin[x]; i; i = Next[i]) { int y = To[i]; int tmp = Dis[y] - Dis[x] + W[i]; if (tmp <= k) { int sum = dfs(y, k - tmp); if (sum == -1) return Dp[x][k] = -1; (Dp[x][k] += sum) %= Mod; } } In[x][k] = 0; return Dp[x][k]; }
intmain() { #ifndef ONLINE_JUDGE freopen("park.in", "r", stdin); freopen("park.out", "w", stdout); #endif int Test = read(); while (Test--) { Init(); Dijkstra :: init(); N = read(), M = read(), K = read(), Mod = read(); for (int i = 1; i <= M; ++i) { int x = read(), y = read(), z = read(); add_edge (x, y, z); Dijkstra :: add_edge (y, x, z); } Dijkstra :: work (N); // for (int i = 1; i <= N; ++i) cout<<Dis[i]<<" "; // cout<<endl; printf("%d\n", dfs(1, K)); } return0; }