「Ynoi2015」我回来了

「Ynoi2015」我回来了

如何提升自己的数据结构能力?从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;
}

猜你喜欢

转载自www.cnblogs.com/HenryHuang-Never-Settle/p/solution-P5068.html