1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <bits/stdc++.h> using namespace std;
const int inf = 0x7fffffff; const int maxn = 100010;
struct Node { int x, y; Node(int x, int y): x(x), y(y) {} };
int n, m, k, p, T; vector<Node> v[maxn], s[maxn]; int d[maxn], ans[maxn][60]; bool vis[maxn][60], alive[maxn]; queue<int> q, f;
int dfs(int a, int b) { if (b < 0) { return 0; } else if (vis[a][b] == 1) { return -inf; } else if (ans[a][b] != -1) { return ans[a][b]; } else { vis[a][b] = true; int key = 0; if (a == n) { key++; } for (int i = 0; i < v[a].size(); ++i) { int g = v[a][i].x, y = v[a][i].y; int u = d[g] - d[a]; if (alive[g] == 0) { continue; } int w = dfs(g, b - (y - u)); if (w == -inf) { return -inf; } else { key = (key + w) % p; } } ans[a][b] = key % p; vis[a][b] = false; return key; } }
void safe() { f.push(n); alive[n] = 1; while (!f.empty()) { int h = f.front(); f.pop(); for (int i = 0; i < s[h].size(); ++i) { int g = s[h][i].x; if (alive[g] == 0) { alive[g] = 1; f.push(g); } } } return ; }
void spfa() { q.push(1); d[1] = 0; while (!q.empty()) { int h = q.front(); q.pop(); for (int i = 0; i < v[h].size(); ++i) { int g = v[h][i].x, y = v[h][i].y; if (d[h] + y < d[g]) { d[g] = d[h] + y; q.push(g); } } } return ; }
int main() { scanf("%d", &T); while (T--) { scanf("%d %d %d %d", &n, &m, &k, &p); for (int i = 1; i <= n; ++i) { v[i].clear(); s[i].clear(); alive[i] = 0; for (int j = 0; j <= k; ++j) { ans[i][j] = -1; vis[i][j] = 0; } } for (int i = 0; i < m; ++i) { int a, b, c; scanf("%d %d %d", &a, &b, &c); v[a].push_back(Node(b, c)); s[b].push_back(Node(a, c)); } for (int i = 2; i <= n; ++i) { d[i] = inf; } spfa(); safe(); int z = dfs(1, k); if (z == -inf) { printf("-1\n"); } else { printf("%d\n", z); } } return 0; }
|