Luogu 3645 [APIO 2015] 雅加达的摩天楼

2023-05-16

          • 传送门
          • 思路
          • 正解
          • 参考代码
          • Update

传送门
思路

  唉,我太弱了,我都看出来要分块了,就是做不来。不过终于把题读对了。

  先来看子任务三怎么做。显然可以有一个 O(m2) O ( m 2 ) 的连边,然后直接跑最短路就可以了。但是分好少啊 QAQ,所以我们来看子任务四。我们将在同一个位置的 doge 构成一个零环,然后只向不在同一个位置的 doge 连边,且对于每个位置最多只连接一次边。这样的时间复杂度就是 O(nm) O ( n m ) 的了。

  注意,连边只能是 doge 连 doge,不能在位置上跳着跳着连。例如,如果非要把位置作为结点,则只能连 13 1 → 3 15 1 → 5 (注意还要加上边权),不能连两条边权为 1 1 13 35 3 → 5 。(想一想,为什么)

正解

  我们可以拆点。我们令位置为结点,对于每个位置,我们把它拆成 k+1 k + 1 个结点,其中 k k 为参数。对于被拆的点,我们从 0 开始编号, 0 0 号点表示位置本身,i(i>0) 号点表示“ i i 步快速通道”,即向左右的 i 步快速通道连一条边权为 1 1 的边。

  如上图,如果某个位置有一个跳跃能力为 k 的 doge,我们就从那个位置的 0 0 号点向 k 步快速通道连一条边权为 0 0 的有向边。另外,我们要保证能够从快速通道回到原结点,所以所有快速通道都要向原结点连一条边权为 0 的有向边。

  其实,这个做法与其叫拆点,不如叫拆边:


边太多了,真难受


这下好多了(雾)

  显然这么做会有 O(nk) O ( n k ) 个结点,多出 O(nk) O ( n k ) 条边,因此 k k 不能太大,也不能太小。对于跳跃能力小于 k 的情况,我们选择建立快速通道,额外时间复杂度为 O(1) O ( 1 ) ;对于剩下的我们暴力建边,额外时间复杂度 O(nk) O ( n k ) 。我们不妨令 nk=nm2k n k = n m 2 k ,解得 k=m2 k = m 2 ,即理论上让 k=120 k = 120 左右就好了,实际上由于每只 doge 跳跃能力的不确定(我这里假设两种情况五五开), k k 到底等于多少才好需要调参。

参考代码

  由于边数很多,所以我们直接判断就好了,无需手动建图。

  另外,上面的参数已经能够满足要求了。调成 m4 更快。

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef int INT_PUT;
INT_PUT readIn()
{
    INT_PUT a = 0; bool positive = true;
    char ch = getchar();
    while (!(ch == '-' || std::isdigit(ch))) ch = getchar();
    if (ch == '-') { positive = false; ch = getchar(); }
    while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }
    return positive ? -a : a;
}
void printOut(INT_PUT x)
{
    char buffer[20]; int length = 0;
    if (x < 0) putchar('-'); else x = -x;
    do buffer[length++] = -(x % 10) + '0'; while (x /= 10);
    do putchar(buffer[--length]); while (length);
}

int INF;
const int maxn = 30005;
int n, m;

#define RunInstance(x) delete new x
struct work
{
    static const int maxk = 90;
    int k;
    std::vector<std::vector<int> > appear;
    std::vector<std::vector<int> > fast;
    std::vector<std::vector<int> > slow;
    int pos[maxn];
    int val[maxn];

    static const int size = maxn * maxk;
    int dis[size];
    bool inQ[size];
    int q[size];
    int head, tail;

    void slack(int from, int to, int cost)
    {
        if (dis[from] + cost < dis[to])
        {
            dis[to] = dis[from] + cost;
            if (!inQ[to])
            {
                q[tail] = to;
                tail = tail + 1 == size ? 0 : tail + 1;
                inQ[to] = true;
            }
        }
    }

    void SPFA()
    {
        head = tail = 0;
        memset(dis, 0x3f, sizeof(dis));
        memset(inQ, 0, sizeof(inQ));
        dis[pos[0]] = 0;
        q[tail++] = pos[0];
        inQ[pos[0]] = true;
        while (head != tail)
        {
            int from = q[head];
            inQ[from] = false;
            head = head + 1 == size ? 0 : head + 1;
            if (from >= n)
            {
                int way = from / n;
                int idx = from - way * n;
                int to;
                if (idx - way >= 0)
                    slack(from, from - way, 1);
                if (idx + way < n)
                    slack(from, from + way, 1);
                slack(from, idx, 0);
            }
            else
            {
                for (int i = 0; i < fast[from].size(); i++)
                    slack(from, from + n * fast[from][i], 0);
                for (int i = 0; i < slow[from].size(); i++)
                {
                    register int cnt;
                    register int step = slow[from][i];
                    register int cost;
                    cnt = from - step;
                    cost = 1;
                    while (cnt >= 0)
                    {
                        slack(from, cnt, cost);
                        cnt -= step;
                        cost++;
                    }
                    cnt = from + step;
                    cost = 1;
                    while (cnt < n)
                    {
                        slack(from, cnt, cost);
                        cnt += step;
                        cost++;
                    }
                }
            }
        }
    }

    work() : dis(), inQ()
    {
        k = std::sqrt(m / 4);
        appear.resize(n);
        fast.resize(n);
        slow.resize(n);
        for (int i = 0; i < m; i++)
        {
            pos[i] = readIn();
            val[i] = readIn();
            appear[pos[i]].push_back(i);
            if (val[i] <= k) fast[pos[i]].push_back(val[i]);
            else slow[pos[i]].push_back(val[i]);
        }
        for (int i = 0; i < n; i++)
        {
            std::sort(fast[i].begin(), fast[i].end());
            fast[i].resize(std::unique(fast[i].begin(), fast[i].end()) - fast[i].begin());
            std::sort(slow[i].begin(), slow[i].end());
            slow[i].resize(std::unique(slow[i].begin(), slow[i].end()) - slow[i].begin());
        }

        SPFA();
        if (dis[pos[1]] >= INF)
            printOut(-1);
        else
            printOut(dis[pos[1]]);
    }
};

void run()
{
    memset(&INF, 0x3f, sizeof(INF));
    n = readIn();
    m = readIn();
    RunInstance(work);
}

int main()
{
    run();
    return 0;
}
Update

  好像这是个 01 BFS……你懂的……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Luogu 3645 [APIO 2015] 雅加达的摩天楼 的相关文章

  • Visual Studio 2017/2015远程调试Linux程序(opencv)

    liu
  • 面试经历---YY欢聚时代(2015年11月21日上午初试、25日下午复试)

    YY欢聚时代一年多前去面试过一次 xff0c 当时鄙视了 xff0c 在现在的公司呆了1年半了 xff0c 感觉做得很不爽 xff0c 而且薪资又不满意 xff0c 所以想找个新工作 xff0c 就想去YY面试 下面将两次YY面试的经历写出
  • 颜色代码表#FFFFFF #FF0000 #00FF00 #FF00FF (2015-07-21 10:39)转载

    标签 xff1a 颜色代码表 白色 ffffff 红色 ff0000 黑色 000000 it 分类 xff1a hht 1 白色 FFFFFF 2 红色 FF0000 3 绿色 00FF00 4 蓝色 0000FF 5 牡丹红 FF00F
  • 【2015-2016,我在路上】

    前言 xff1a 每天 xff0c 每时 xff0c 每分 xff0c 时光的步伐永远不会停止 xff0c 当我提起笔 xff0c 写下的这一瞬间 xff0c 时间又是一年 xff0c 一年的时光 xff0c 在没逝去时 xff0c 感觉很
  • 2015-2016 ACM-ICPC Pacific Northwest Regional Contest Div.2( Problem V Gears)

    题目地址 xff1a 点击打开链接 题意 xff1a 给你很多齿轮 xff0c 让你判断第一个齿轮和第n个齿轮的关系 有三种关系题目中已经给出 解题思路 xff1a 算是比较直观的一个dfs题目了 xff0c 重点是怎么样处理这个dfs 结
  • VS 2015运行报错

    VS 2015运行报错 xff1a L N K 1104 无法打开文件 kernel 32 lib xff0c L N K 1158 xff1a 无法运行 34 r c e x e xff0c L N K 156 必须定义入口点 34 的问
  • luogu P2078 朋友

    题目背景 小明在A公司工作 xff0c 小红在B公司工作 题目描述 这两个公司的员工有一个特点 xff1a 一个公司的员工都是同性 A公司有N名员工 xff0c 其中有P对朋友关系 B公司有M名员工 xff0c 其中有Q对朋友关系 朋友的朋
  • please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 was installed with the Visual C++ option

    first rustup toolchain install stable x86 64 pc windows gnu then rustup default stable x86 64 pc windows gnu end cargo b
  • 安装Visual Studio 2015时出现安装包丢失或损坏

    1 现象描述 在线安装vs时 xff0c 在线下载一直为0 xff0c 提示网络异常 xff0c 检查网络 xff1b 实际网络是能联网的 离线安装ISO xff0c 安装1分钟左右 提示安装包损坏或丢失 xff0c 选择从inter下载或
  • Luogu 3631 [APIO 2011] 方格染色

    传送门思路参考代码细节 传送门 思路 很不错的一道题 xff0c 用到的东西不深 xff0c 但是要想到确实需要一定思维 一开始我想的是动态规划 xff0c 发现如果要设状态需要知道一个格子左边 xff0c 上边和左上边三个格子的状态 然后
  • Luogu 1552 [APIO 2012] 派遣

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题读错了两次 xff0c 一开始读成了一个一般的背包 xff0c 然后读成了一个价值和花费相同的背包 xff0c 最后才发现原来是一个价值为 1
  • Luogu 3778 [APIO 2017] 商旅

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 看到这道题就想到了二分答案找负环 xff0c 但是怎么做呢 xff1f 完全不会 唉 xff0c 我太弱啦 xff01 先注意题目中说可以重复经过点和边 x
  • Luogu 2146 [NOI 2015] 软件包管理器

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 好不容易遇到一道傻逼题 xff0c 又出了个傻逼错误 xff0c 爆得只剩 30 30 分了 唉 xff0c 我太弱啦 xff01 显然 xff
  • Luogu 2168 [NOI 2015] 荷马史诗

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 连哈夫曼树都不会 这道题就是一个 k k 叉哈夫曼树 题目要求满足两个条件 一是代价最小 二是最长长度最小 最长长度最小很好解决 只需要优先合并
  • APIO 2018 游记

    Day 0Day 1Day 2Day 3Day 4 Day 0 早上 4 4 点就上车去机场赶那 7 7 点的飞机 感觉很困 xff0c 所以在飞机上就这么睡过去了 北京是个好地方 xff0c 但是与我无关 下飞机后 xff0c 我们一行人
  • 再见2014,你好2015

    过去就是过去了 2014年再见 xff0c 2015年你好 xff01 回首 总结也只是慰藉 1999年12月至今 xff0c 经历了整整十五个曾经 xff0c 这其中的波折 xff0c 怎是我这样的小辈能够理解的 借这个平台也只是为了感谢
  • 浙江省赛2015 _ J - Convert QWERTY to Dvorak -> ZOJ 3878

    模拟水题 题目 xff1a ZOJ 3878 Edward a poor copy typist is a user of the Dvorak Layout But now he has only a QWERTY Keyboard wi
  • 百度2015校园招聘软件开发笔试题及答案

    简单题 xff08 本题共30分 xff09 请简述Tcp ip的3次握手以及4次挥手过程 xff1f 并解释为何关闭连接需要4次挥手 10分 详细答案参见TCP IP协议三次握手与四次握手流程解析 TCP三次握手 四次挥手过程如下 通常情
  • P1586 四方定理

    Powered by NEFU AB IN Link 文章目录 P1586 四方定理 题意 思路 代码 P1586 四方定理 题意 四方定理是众所周知的 任意一个正整数n 可以分解为不超过四个整数的平方和 给定的正整数n 编程统计它能分解的
  • 再见2015,一个小白领的格调

    当我一直沉默着做事情的时候 时间就像一条脱缰的野狗一样 肆意狂奔 快到让我忘记了买回老家过冬的衣服便放春节了 以至于现在我还满脑子的考虑穿什么过冬 而不是感叹15年已经过完 2015年1月1日 六个小伙伴在吃烤肉 依次诉说各自的新年计划 我

随机推荐

  • 2022 New Year‘s Resolution

    Some Might Say 2022 New Year 39 s Resolution Some might say we are on the edge of the new era Always are they saying thi
  • C++ 多线程编程导论(中)

    受篇幅限制 xff0c 上半部分不再更新 xff0c 填坑的新内容都放在此文章中 文章目录 参考资料线程安全 xff08 续 xff09 互斥访问 互斥体 xff08 mutex xff09 和锁 xff08 lock xff09 什么是互
  • C++ 使用模板序列化/反序列化固定键值对

    仅是一个原型 xff0c 留作记录 我感觉可以写出非常逆天的代码 span class token macro property span class token directive hash span span class token d
  • 编译原理习题两则(龙书,写出语言的正则定义)

    3 3 5 3 注释 xff0c 即 和 之间的串 xff0c 且串中没有不在双引号 xff08 34 xff09 中的 注 xff1a 假设双引号是匹配的 思路 xff1a 从空串开始写 xff0c 写出整体框架后 xff0c 通过分类讨
  • 2023 New Year‘s Resolution

    This Is Game 2023 New Year 39 s Resolution My 2022 ended with a day of game I am convinced that I am not to blame becaus
  • 补录:2018 和 2019 New Year‘s Resolution

    前言 xff1a 吉光片羽 xff0c 以飨读者 2018 New Year 39 s Resolution One year and a half ago I felt that life in 2020 would be quite d
  • 原博文地址

    由于账号问题 xff0c 现更改为这个账号 xff0c 以下为原博文地址 使用WH MOUSE LL钩子来判断按键是否是mouse event模拟的 http blog csdn net qq 26140973 article detail
  • [NOI 2003] 文本编辑器 Splay 维护序列 / 块状链表

    传送门 xff08 JZOJ xff09 xff08 第一道全国决赛题 xff09 解法 1 xff1a 使用 Splay 维护 不管怎么说 xff0c 总和刚刚学过的迎合上了 这道题可以直接上 Splay 维护线性序列 xff0c 光标位
  • 一次macOS的升级填坑(macOS Catalina - macOS Monterey)

    目录 小序一 升级前操作二 升级中三 问题填坑1 像我一样长时间卡在一个进度条怎么办2 在更新途中重启过电脑 xff08 完整流程填坑 xff09 3 安装之后不能开机 xff0c 如何紧急拷贝资料4 安装不成功 xff0c 如何重新安装系
  • CF 713C Sonya and Problem Wihtout a Legend

    文章目录 传送门题目大意正解通过维护关键点来维护信息参考代码 传送门 题目大意 给定一个长度为 n n 3000
  • Luogu 3642 [APIO 2016] 烟火表演

    传送门引例 xff08 上一道题 xff09 凸函数一开始的思路正解参考代码总结 传送门 引例 xff08 上一道题 xff09 凸函数 回忆我们上一道题是怎么做的 我们维护的东西的实质是一个 xff08 下 xff09 凸函数 由于我们的
  • Luogu 3631 [APIO 2011] 方格染色

    传送门思路参考代码细节 传送门 思路 很不错的一道题 xff0c 用到的东西不深 xff0c 但是要想到确实需要一定思维 一开始我想的是动态规划 xff0c 发现如果要设状态需要知道一个格子左边 xff0c 上边和左上边三个格子的状态 然后
  • Luogu 3632 [APIO 2011] 寻路

    传送门正解参考代码 传送门 正解 暴力连边跑最短路就好了 xff0c 只不过代码太长太难写啦 xff01 参考代码 span class hljs preprocessor include lt cstdio gt span span cl
  • Luogu 3634 [APIO 2012] 守卫

    传送门思路正解参考代码 传送门 思路 感觉自己越来越笨了 首先 xff0c 很明显这道题需要把没有看到忍者的区间给删去 xff0c 可以用前缀和 O n O n 处理 xff0c 然后对没有删去的地方重新标号 重新标号时 xff0c 需要对
  • Luogu 1552 [APIO 2012] 派遣

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题读错了两次 xff0c 一开始读成了一个一般的背包 xff0c 然后读成了一个价值和花费相同的背包 xff0c 最后才发现原来是一个价值为 1
  • 贪玩 CF 之旅

    文章目录 CF 7D Palindrome Degree http codeforces com problemset problem 7 D 题解 CF 713C Sonya and Problem Wihtout a Legend ht
  • Luogu 3638 [APIO 2013] 机器人

    传送门思路正解参考代码关于 SPFA 传送门 思路 n n 这么小 会不会是搜索题 稍有经验的我直接否定了这个结论 仔细读题并分析样例 发现原来一个位置可以有多个机器人 且机器人行走的时候无视其它机器人 那这个就是一张图啊 可以将这张图预处
  • Luogu 3647 [APIO 2014] 连珠线

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 又看错题了 题目中说一个新的珠子和一个已经添加的珠子连接起来 xff0c 我没有看到 xff0c 然后就凉了 立个 flag xff1a 已经连续看错五题了 xff0c
  • 【转】mingw64的安装方法

    转自 xff1a http write blog csdn net postlist mingw64的安装方法 1 下载ming w64 http sourceforge net projects mingw w64 files or x8
  • Luogu 3645 [APIO 2015] 雅加达的摩天楼

    传送门思路正解参考代码Update 传送门 思路 唉 xff0c 我太弱了 xff0c 我都看出来要分块了 xff0c 就是做不来 不过终于把题读对了 先来看子任务三怎么做 显然可以有一个 O m 2 O m 2