zoukankan      html  css  js  c++  java
  • [JZOJ 5875] [NOIP2018提高组模拟9.20] 听我说,海蜗牛 解题报告(BFS+二分)

    题目链接:

    http://172.16.0.132/senior/#main/show/5875

    题目:

    题解:

    注意这题只能经过开放的港口

    我们考虑用vector存下每个点不能到的点,并把并让vector里面的元素升序排序,这样我们就可以二分查找一个点是否与另外一个点相连

    接下来我们对于每一个开放的港口bfs,每次bfs都把属于这个连通块的港口去掉

    考虑开两个队列来bfs,队列1存储的是当前连通块里还没有拓展的点,队列2里存储的是还剩下的点,看看代码就可以理解了

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<queue>
    using namespace std;
    
    const int N=1e5+15;
    int n,m,t;
    struct E{
        int x,y;
    }e[N<<2];
    vector <int> p[N];
    queue <int> Q;
    inline int read(){
        char ch=getchar();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    bool cmp(E a,E b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    int find(int u,int v){
        int l=0,r=p[u].size()-1;
        if (l>r) return -1;
        while (l<=r){
            if (l==r) return p[u][l];
            int mid=l+r>>1;
            if (p[u][mid]>v) r=mid-1;else 
            if (p[u][mid]<v) l=mid+1;else 
            if (p[u][mid]==v) return p[u][mid];
        }
        return p[u][l];
    }
    void bfs(int x){
        queue <int> qq,q;
        qq.push(x);
        while (!qq.empty())
        {
            int u=qq.front();qq.pop();
            while (!Q.empty()){
                int v=Q.front();Q.pop();
                if (find(u,v)!=v) qq.push(v);
                else q.push(v);
            }
            while (!q.empty()){
                int v=q.front();q.pop();
                Q.push(v);
            }
        }
    }
    int main(){
        freopen("connect.in","r",stdin);
        freopen("connect.out","w",stdout);
        n=read();m=read();t=read();
        int cnt=0;
        for (int i=1;i<=m;i++){
            ++cnt;
            e[cnt].x=read();e[cnt].y=read();
            ++cnt;
            e[cnt].x=e[cnt-1].y;e[cnt].y=e[cnt-1].x;
        }
        sort(e+1,e+1+cnt,cmp);
        for (int i=1;i<=cnt;i++) p[e[i].x].push_back(e[i].y);
        while (t--){
            int k=read(),ans=0;
            while (!Q.empty()) Q.pop();
            for (int i=1;i<=k;i++){
                int s=read();
                Q.push(s);
            }
            while (!Q.empty()){
                int s=Q.front();Q.pop();
                bfs(s);++ans;
            }
            printf("%d
    ",ans);
        }  
        return 0;
    }
  • 相关阅读:
    qt一些函数
    js时间字符串转时间戳
    golang学习之interface与其它类型转换
    golang学习之奇葩的time format
    windows下安装mongodb
    golang学习之struct
    golang学习之闭包
    js生成6位随机码
    golang学习之生成代码文档
    moment常用操作
  • 原文地址:https://www.cnblogs.com/xxzh/p/9806478.html
Copyright © 2011-2022 走看看