「Ynoi2015」我回来了

「Ynoi2015」我回来了

这东西已经不是 Ynoi 了,因为太水被嫌弃了。
如何提升自己的数据结构能力?从Ynoi做起

题目链接

其实这个题很小清新的辣,而且不卡常。

由于边权为 \(1\),所以 \(\texttt{BFS}\) 预处理出任意两点间距离。

记录 \(f[i][j]\) 为与点 \(i\) 距离 \(\le j\) 的点的集合。

这里我们可以使用 \(\texttt{bitset}\) 维护。

然后每次将对应的集合并上去即可。

时间复杂度 \(O(\max(n(n+m),\frac{n^3+\sum k}{w}))\)

贴代码

/*---Author:HenryHuang---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
bitset<maxn> f[maxn][maxn];
vector<int> d[maxn];
int dis[maxn];
int n,m,T;
void bfs(int x){
	queue<int> Q;
	memset(dis,0,sizeof dis);
	Q.push(x);
	while(!Q.empty()){
		int u=Q.front();Q.pop();
		for(auto v:d[u]){
			if(!dis[v]&&v!=x){
				dis[v]=dis[u]+1;
				Q.push(v);
			}
		}
	}
	for(int i=1;i<=n;++i)
		if(dis[i]!=0||i==x)
			f[x][dis[i]].set(i);
	for(int i=1;i<=n;++i)
		f[x][i]|=f[x][i-1];
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m>>T;
	for(int i=1;i<=m;++i){
		int a,b;
		cin>>a>>b;
		d[a].emplace_back(b),d[b].emplace_back(a);
	}
	for(int i=1;i<=n;++i) bfs(i);
	while(T--){
		int k;
		cin>>k;
		bitset<maxn>ans;
//		ans.set();
		for(int i=1;i<=k;++i){
			int x,y;
			cin>>x>>y;
			ans|=f[x][y];
		}
		cout<<ans.count()<<'\n';
	}
	return 0;
}
posted @ 2020-02-07 17:24  Henry__Huang  阅读(196)  评论(0编辑  收藏  举报