【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 50005 #define INF 1e18 #define P 1000000007 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct info {long long value; int pos; }; bool operator < (info a, info b) {return a.value > b.value; } int n, m, s, t; int x[MAXN], y[MAXN], z[MAXN]; vector <int> a[MAXN]; vector <int> b[MAXN]; priority_queue <info> Heap; long long dist[MAXN]; bool finished[MAXN]; bitset <MAXN> seta[MAXN], setb[MAXN]; map <int, bitset <MAXN> > f; long long cnta[MAXN], cntb[MAXN]; void worka(int pos) { cnta[pos] = (pos == t); seta[pos].set(pos); if (pos == t) return; for (unsigned i = 0; i < a[pos].size(); i++) { worka(a[pos][i]); cnta[pos] += cnta[a[pos][i]]; cnta[pos] %= P; if (cnta[a[pos][i]]) seta[pos] |= seta[a[pos][i]]; } } void workb(int pos) { cntb[pos] = (pos == s); setb[pos].set(pos); if (pos == s) return; for (unsigned i = 0; i < b[pos].size(); i++) { workb(b[pos][i]); cntb[pos] += cntb[b[pos][i]]; cntb[pos] %= P; if (cntb[b[pos][i]]) setb[pos] |= setb[b[pos][i]]; } } int main() { read(n), read(m), read(s), read(t); for (int i = 1; i <= m; i++) { read(x[i]), read(y[i]), read(z[i]); if (z[i] == 0) continue; a[x[i]].push_back(y[i]); a[y[i]].push_back(x[i]); b[x[i]].push_back(z[i]); b[y[i]].push_back(z[i]); } for (int i = 1; i <= n; i++) dist[i] = INF; dist[s] = 0; Heap.push((info) {0, s}); while (!Heap.empty()) { while (!Heap.empty() && finished[Heap.top().pos]) Heap.pop(); if (Heap.empty()) break; info tmp = Heap.top(); Heap.pop(); for (unsigned i = 0; i < a[tmp.pos].size(); i++) if (tmp.value + b[tmp.pos][i] < dist[a[tmp.pos][i]]) { dist[a[tmp.pos][i]] = tmp.value + b[tmp.pos][i]; Heap.push((info) {dist[a[tmp.pos][i]], a[tmp.pos][i]}); } } for (int i = 1; i <= n; i++) a[i].clear(); for (int i = 1; i <= n; i++) b[i].clear(); for (int i = 1; i <= m; i++) { if (z[i] == 0) continue; if (dist[x[i]] + z[i] == dist[y[i]]) a[x[i]].push_back(y[i]), b[y[i]].push_back(x[i]); if (dist[y[i]] + z[i] == dist[x[i]]) a[y[i]].push_back(x[i]), b[x[i]].push_back(y[i]); } worka(s); workb(t); for (int i = 1; i <= n; i++) { cnta[i] = cnta[i] * cntb[i] % P; seta[i] |= setb[i]; seta[i].set(i); f[cnta[i]].set(i); } long long ans = 0; for (int i = 1; i <= n; i++) { int tmp = (cnta[t] - cnta[i] + P) % P; ans += (f[tmp] & (~seta[i])).count(); } cout << ans / 2 << endl; return 0; }