题目大意:给你一张$n(nleqslant10^3)$个点$m(mleqslant10^5)$个点的无向无权图,多组询问,每次询问给你一些二元组$(x_i,y_i)$,求有多少个$u$于至少一个二元组满足:$dis(u,x_i)leqslant y_i$
题解:对每个点跑一遍$bfs$,求出每个点到达其他点的距离,按距离前缀和一下(就是说变成小于等于这个距离是哪几个点),$f_{i,j}$表示到第$i$个点距离小于等于$j$的点有哪些,查询时把答案与$f_{x,y}$求个并集就行了,可以用$bitset$优化
复杂度:$O(dfrac{n^3}{omega})$,可以通过
卡点:用前向星存边被卡常,需要用$vector$(可能是因为边数较大,$vector$内存访问连续)
C++ Code:
#include <iostream> #include <cstring> #include <bitset> #include <vector> #define maxn 1024 #define maxm 100010 const int inf = 0x3f3f3f3f; std::vector<int> e[maxn]; int n, m, Q; std::bitset<maxn> v[maxn][maxn]; int d[maxn], q[maxn], h, t; int MAXL[maxn]; void bfs(int S, std::bitset<maxn> *v) { memset(d, 0, sizeof d); q[h = t = 0] = S; while (h <= t) { int u = q[h++]; v[d[u]].set(u); const std::vector<int>::iterator End = e[u].end(); for (std::vector<int>::iterator it = e[u].begin(); it != End; ++it) { int v = *it; if (v != S && !d[v]) { d[v] = d[u] + 1; q[++t] = v; } } } const int M = d[q[t]]; for (int i = 1; i <= M; i++) v[i] |= v[i - 1]; MAXL[S] = M; } int main() { std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); std::cin >> n >> m >> Q; for (int i = 0, a, b; i < m; i++) { std::cin >> a >> b; e[a].push_back(b); e[b].push_back(a); } for (int i = 1; i <= n; i++) bfs(i, v[i]); while (Q --> 0) { std::bitset<maxn> ans; int T; std::cin >> T; while (T --> 0) { int x, y; std::cin >> x >> y; if (y > MAXL[x]) y = MAXL[x]; ans |= v[x][y]; } std::cout << ans.count() << ' '; } return 0; }