【洛谷P5068】我回来了【bfs】
题目
题目链接:https://www.luogu.com.cn/problem/P5068
珂朵莉给你一个无向图,每次查询的时候给一堆二元组
求图中有多少个点与至少一个这次询问给出的二元组满足,表示这两个点在图中的距离
如果不连通
思路:
第一次写出来的题。虽然这是Ynoi为数不多的良心题(雾
设表示距离点最短路长度不超过的节点集合,那么我们只要求出长度等于的节点集合,然后或上即可。
对于每一个点进行一次即可求出。
然后对于每一次询问,其实答案节点集合就是。
的类型是自带的。每一位只能是0或1,占用空间。
时间复杂度玄学。
还有洛谷讨论区中说这道题似乎卡邻接表。。。用存边即可。
代码:
#include <queue>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1010,M=100010,Inf=1e9;
int n,m,Q,x,y,t,tot,dis[N];
bitset<N> p[N][N];
vector<int> e[N];
inline int read()
{
int d=0; char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9')
d=(d<<3)+(d<<1)+ch-48,ch=getchar();
return d;
}
inline void bfs(int S)
{
memset(dis,0x3f3f3f3f,sizeof(dis));
queue<int> q;
q.push(S); dis[S]=0; p[S][0][S]=1;
while (q.size())
{
int u=q.front();
q.pop();
for (register int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if (dis[v]>Inf)
{
dis[v]=dis[u]+1;
p[S][dis[v]][v]=1;
q.push(v);
}
}
}
for (register int i=1;i<N;i++)
p[S][i]|=p[S][i-1];
}
signed main()
{
n=read(); m=read(); Q=read();
for (register int i=1;i<=m;i++)
{
x=read(); y=read();
e[x].push_back(y);
e[y].push_back(x);
}
for (register int i=1;i<=n;i++)
bfs(i);
while (Q--)
{
t=read();
bitset<N> ans(0);
while (t--)
{
x=read(); y=read();
ans|=p[x][y];
}
printf("%d\n",ans.count());
}
return 0;
}