zoukankan      html  css  js  c++  java
  • [BFS][bitset]luogu P3645 [APIO2015]雅加达的摩天楼

    题面

    https://www.luogu.com.cn/problem/P3645

    分析

    BFS即可,因为是无权无向图

    如果设不重复状态 (i,j) 表示第 i 个楼上的狗子跳跃能力为 j ,那么至多有  $max(n,m)sqrt{n}$ 种状态

    不难证明,若 $jleq sqrt{n}$ 则至多有 $nsqrt{n}$ 种, $j> sqrt{n}$ 则至多有 $msqrt{n}$ 种(狗子最多有m个)

    然后对于每个第一次BFS到的大楼,将所有的狗子都加入队列,如果不是第一次到,判断该状态是否出现过,未出现再加入,即可保证复杂度严格为$ O((n+m)sqrt{n})$

    判重可以用 bitset 或者 hash(手写,别用unordered_map)

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    const int N=3e4+10;
    struct Doge {
        int pos,p,step;
    };
    int n,m;
    int b[N],p[N];
    bitset<N> w[N];
    queue<Doge> q;
    vector<int> v[N];
    bool vis[N];
    
    void BFS() {
        for (int i=0;i<v[b[0]].size();i++) if (!w[b[0]].test(v[b[0]][i])) q.push((Doge){b[0],v[b[0]][i],0}),w[b[0]].set(v[b[0]][i]);vis[b[0]]=1;
        while (!q.empty()) {
            Doge u=q.front();q.pop();
            if (u.pos==b[1]) {printf("%d
    ",u.step);return;}
            if (u.pos-u.p>=0) {
                if (!vis[u.pos-u.p])
                    for (int i=0;i<v[u.pos-u.p].size();i++) if (!w[u.pos-u.p].test(v[u.pos-u.p][i])) q.push((Doge){u.pos-u.p,v[u.pos-u.p][i],u.step+1}),w[u.pos-u.p].set(v[u.pos-u.p][i]);
                vis[u.pos-u.p]=1;
                if (!w[u.pos-u.p].test(u.p)) q.push((Doge){u.pos-u.p,u.p,u.step+1}),w[u.pos-u.p].set(u.p);
            }
            if (u.pos+u.p<n) {
                if (!vis[u.pos+u.p])
                    for (int i=0;i<v[u.pos+u.p].size();i++) if (!w[u.pos+u.p].test(v[u.pos+u.p][i])) q.push((Doge){u.pos+u.p,v[u.pos+u.p][i],u.step+1}),w[u.pos+u.p].set(v[u.pos+u.p][i])=1;
                vis[u.pos+u.p]=1;
                if (!w[u.pos+u.p].test(u.p)) q.push((Doge){u.pos+u.p,u.p,u.step+1}),w[u.pos+u.p].set(u.p);
            }
        }
        printf("-1
    ");
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=0;i<m;i++) scanf("%d%d",&b[i],&p[i]),v[b[i]].push_back(p[i]);
        BFS();
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    2015长春区域赛感想
    己亥清爽恢复系列之数据文件1篇:SYSTEM物理损坏或丢失(关键表空间)
    ecshop和jQuery冲突
    ecshop广告分析
    ecshop商品页增加编辑器fckeditor
    DIV自适应高度
    打个招呼
    jdk的wsimport方法实现webservice客户端调用服务
    jdk自带发布webservice服务
    Mysql数据库基本配置
  • 原文地址:https://www.cnblogs.com/mastervan/p/14578919.html
Copyright © 2011-2022 走看看