#include #include #include using namespace std; #define fre \ freopen("in.txt", "r", stdin); \ freopen("out.txt", "w", stdout) #define abs(x) ((x) > 0 ? (x) : -(x)) #define MOD 1000000007 #define LL signed long long int #define scan(x) scanf("%d", &x) #define print(x) printf("%d\n", x) #define scanll(x) scanf("%lld", &x) #define printll(x) printf("%lld\n", x) #define rep(i, from, to) for (int i = (from); i <= (to); ++i) #define pii pair #define INF 10000000000000000LL #define MAXV 10000 #define MAXN 16 int V, E, N, S, F; vector G[MAXV + 1]; vector students; LL dist[MAXV + 1], dist2[1 << MAXN][MAXN], sp2[1 << MAXN]; LL sp[MAXN + 1][MAXN + 1], spS[MAXN + 1], spF[MAXN + 1]; LL talk[MAXN + 1], stalk[1 << MAXN], dp[1 << MAXN]; int P[MAXN + 4]; bool isStudent[MAXV + 1]; void computeSP(int s) { int source = students[s]; for (int i = 1; i <= V; ++i) { dist[i] = INF; } set> Q; Q.insert({0, source}); dist[source] = 0; while (not Q.empty()) { LL v = Q.begin()->second; Q.erase(Q.begin()); for (auto x : G[v]) { int w = x.second; int u = x.first; if (isStudent[u]) continue; if (dist[u] > dist[v] + w) { Q.erase({dist[u], u}); dist[u] = dist[v] + w; Q.insert({dist[u], u}); } } } sp[s][s] = 0; for (int i = 0; i < N; ++i) { if (s == i) continue; int dest = students[i]; for (auto x : G[dest]) { int w = x.second; int u = x.first; sp[s][i] = min(sp[s][i], dist[u] + w); } } spS[s] = dist[S]; spF[s] = dist[F]; } void computeSP2() { set> Q; for (int mask = 0; mask < (1 << N); ++mask) { sp2[mask] = INF; for (int i = 0; i < N; ++i) { dist2[mask][i] = INF; } } for (int i = 0; i < N; ++i) { if (spS[i] == INF) continue; Q.insert({spS[i], {1 << i, i}}); dist2[1 << i][i] = spS[i]; } while (not Q.empty()) { int mask = Q.begin()->second.first; int i = Q.begin()->second.second; Q.erase(Q.begin()); sp2[mask] = min(dist2[mask][i] + spF[i], sp2[mask]); for (int j = 0; j < N; ++j) { int mask2 = mask | (1 << j); if (dist2[mask2][j] > dist2[mask][i] + sp[i][j]) { Q.erase({dist2[mask2][j], {mask2, j}}); dist2[mask2][j] = dist2[mask][i] + sp[i][j]; Q.insert({dist2[mask2][j], {mask2, j}}); } } } } void computeDP() { for (int mask = 0; mask < (1 << N); ++mask) { dp[mask] = sp2[mask] + stalk[mask]; } dp[0] = 0; for (int i = 0; i < N; ++i) { for (int mask = (1 << N) - 1; mask >= 0; --mask) { if ((mask & (1 << i)) == 0) dp[mask] = min(dp[mask], dp[mask | (1 << i)]); } } } LL pow(LL base, LL exponent, LL modulus = MOD) { LL result = 1; while (exponent > 0) { if (exponent % 2 == 1) result = (result * base) % modulus; exponent = exponent >> 1; base = (base * base) % modulus; } return result; } int main() { cin >> V >> E >> S >> F >> N; for (int i = 0; i < N; ++i) { int s; scan(s); scanll(talk[i]); scan(P[i]); P[i] = (P[i] * pow(100, MOD - 2, MOD)) % MOD; students.push_back(s); isStudent[s] = i + 1; for (int j = 0; j < N; ++j) { sp[i][j] = INF; } } for (int i = 1; i <= E; ++i) { int u, v, w; scan(u); scan(v); scan(w); G[u].push_back({v, w}); G[v].push_back({u, w}); } stalk[0] = 0; for (int mask = 1; mask < (1 << N); ++mask) { stalk[mask] = 1; for (int i = 0; i < N; ++i) { if (mask & (1 << i)) { stalk[mask] = (stalk[mask] * talk[i]) % MOD; } } } for (int i = 0; i < N; ++i) { computeSP(i); } computeSP2(); computeDP(); // for (int mask = 0; mask < (1 << N); ++mask) { // if (dp[mask] == INF) // continue; // for (int i = 0; i < N; ++i) // if (mask & (1 << i)) // cout << students[i]; // cout << ' ' << dp[mask] << ' ' << sp2[mask] + stalk[mask] << endl; // } LL ans = 0; for (int mask = 0; mask < (1 << N); ++mask) { LL prob = 1; for (int i = 0; i < N; ++i) { if (mask & (1 << i)) { prob = (prob * P[i]) % MOD; } else { prob = (prob * (MOD + 1 - P[i])) % MOD; } } ans = (ans + dp[mask] * prob) % MOD; } printll(ans); }