Description
有一个 n n n个点的无向图,有 m m m次查询,每次查询给出一些 ( x i , y i ) (x_i,y_i) (xi,yi)
令 d i s t ( x , y ) dist(x,y) dist(x,y)表示 x x x和 y y y点在图中最短距离, d i s t ( x , x ) = 0 dist(x,x)=0 dist(x,x)=0,如果 x , y x,y x,y不连通则 d i s t ( x , y ) = i n f dist(x,y) = inf dist(x,y)=inf
每次查询图中有多少个点 v v v与至少一个这次询问给出的 ( x i , y i ) (x_i,y_i) (xi,yi)满足 d i s t ( v , x i ) ≤ y i dist(v,x_i)\le y_i dist(v,xi)≤yi
Input
第一行三个数表示 n , m , q n,m,q n,m,q
之后 m m m行每行两个数 x , y x,y x,y表示有一条 x x x与 y y y之间的边,边权为 1 1 1
之后 q q q次询问,每个询问先给你一个数 a a a
之后一行 2 a 2a 2a个数,第 2 i − 1 2i-1 2i−1个数 x i x_i xi和第 2 i 2i 2i个数 y i y_i yi表示一个二元组 ( x i , y i ) (x_i,y_i) (xi,yi)
( n ≤ 1 0 3 , m ≤ 1 0 5 , q ≤ 1 0 5 , ∑ ∣ a ∣ ≤ 2100000 ) (n\le 10^3,m\le 10^5,q\le 10^5,\sum |a|\le 2100000) (n≤103,m≤105,q≤105,∑∣a∣≤2100000)
Output
输出 q q q行,每行一个数表示这次询问的答案
Sample Input
5 6 6
2 3
1 3
2 5
1 3
3 2
2 5
1
3 1
1
1 1
1
1 4
1
5 2
1
1 4
2
1 0 5 1
Sample Output
3
2
4
3
4
3
Solution
从每点开始 b f s bfs bfs,用 f [ i ] [ j ] f[i][j] f[i][j]这个 b i t s e t bitset bitset记录所有与 i i i点距离不超过 j j j的点,那么对于一组查询,把所有 f [ x i ] [ y i ] f[x_i][y_i] f[xi][yi]或一下统计 1 1 1的个数即可,时间复杂度 O ( n 3 32 ) O(\frac{n^3}{32}) O(32n3)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1005;
bitset<1005>f[maxn][maxn],ans;
int n,m,q,dis[maxn];
vector<int>g[maxn];
void bfs(int s)
{
queue<int>que;
que.push(s);
f[s][0].set(s);
memset(dis,-1,sizeof(dis));
dis[s]=0;
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(dis[v]!=-1)continue;
dis[v]=dis[u]+1;
que.push(v);
f[s][dis[v]].set(v);
}
}
for(int i=1;i<=n;i++)f[s][i]|=f[s][i-1];
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v),g[v].push_back(u);
}
for(int i=1;i<=n;i++)bfs(i);
while(q--)
{
int a,x,y;
scanf("%d",&a);
ans.reset();
while(a--)
{
scanf("%d%d",&x,&y);
y=min(y,n);
ans|=f[x][y];
}
printf("%d\n",ans.count());
}
return 0;
}