题目大意:给你一张$n(n\leqslant10^3)$个点$m(m\leqslant10^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() << '\n';
}
return 0;
}