【Codeforces 1137C】Museums Tour
Codeforces 1137 C
题意:给一个有向图,一周有\(d\)天,每一个点在每一周的某些时刻会开放,现在可以在这个图上从\(1\)号点开始随意地走,问最多能走到多少个开放的点。一个点如果重复走到了很多次,只算一次。
思路:这空间太难卡了。。。
我们首先考虑将这个图的所有点都拆成\(d\)个,变成\(n\times d\)个点(为下文卡空间埋下伏笔),
即将\(i\)变成\((i,j)\),其中\(j\)表示到\(i\)的时候是一周的第\(j\)天(这里天数是\(0-start\),即一周的第一天是\(j=0\))
然后将每一条边\(u\rightarrow v\)都变成\((u,i)\rightarrow(v,(i+1)\ mod\ d)\),那么我们就会发现我们要求的就是\((0,0)\)开始我们最多能跑到多少不同的\((i,\star)\)。
所以我们将这个新图强连通分解,对于每一个强连通分量求出这个连通分量中不同的原来点的个数。
为了避免重复计算,我们证明以下结论:
在新图的一条链中出现的所有相同原图节点的节点们必定在同一个新图的强连通分量内。
证明:
首先我们假设这条链中有两个节点\((u,i)\)和\((u,j)\),那么原图上肯定有一个包含\(u\)的环,其长度\(mod\ d\)为\(j-i\),那我们从\((u,j)\)再走\(d-1\)次这个环,肯定回到\((u,i)\)。所以它们两个节点肯定在一个强连通分量内。证毕。
然后我们考虑\(dp(i)\)表示现在走到了第\(i\)个强连通分量,最多能够走到的点的个数。
那么转移就是枚举\(i\rightarrow j\),从\(dp(j)\)转移。
但是,只是这样的话肯定会\(mle\),我们需要卡空间。
我的做法是把所有的关于\(stl\)、递归的东西统统变成手写的,然后就变成了一堆奇奇怪怪的东西:
邻接表我用的是\(vector\),那么不要了!变成前向星!
强连通分解我用的是\(kosaraju\),那么这两个\(dfs\)都不要了!变成手写的递归!
\(dp\)的时候我用的是记忆化搜索,那么这个\(dfs\)也不要了!变成拓扑排序后\(bfs\)!(但是最后还是变成了手写递归-_-
关于手写递归:
首先我们要知道白点、灰点、黑点这三个概念:白点是没有访问过的点,灰点是正在访问的点,黑点是已经访问过了的点。它们分别对应了\(vis\)中的\(0\)、\(1\)、\(2\)。
然后我们手动维护一个调用栈\(stk\),那么我们的\(dfs\)应该是这样的:
// 起始点: s
stk.push(s);
while (!stk.empty()) {
int u = stk.top(); stk.pop();
if (vis[u] == 2) continue;
if (vis[u] == 1) {
// 做正常dfs的时候访问完儿子们后做的事
vis[u] = 2;
continue;
}
for (int v : g[u]) {
if (!vis[v]) stk.push(v);
}
}
十分不优美,但为了卡空间也没什么办法。。。
\(stk\)千万不要用\(std::stack\),肯定会\(tle\)。。。
老老实实手写,如果感觉空间不够也不要用\(vector\)。大胆开不要怂小心地算一个上界开大一点点的(比如加一个微不足道的常数\(10^5\))
【Codeforces 1137C】Museums Tour的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
- 【Codeforces 670C】 Cinema
[题目链接] http://codeforces.com/contest/670/problem/C [算法] 离散化 [代码] #include<bits/stdc++.h> using ...
- 【codeforces 515D】Drazil and Tiles
[题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...
随机推荐
- 汇编语言--微机CPU的指令系统(五)(数据传送指令)
五.微机CPU的指令系统 1.汇编语言指令格式 汇编语言的指令格式如下: 指令助忆符 [操作数1 [, 操作数2 [, 操作数3]]] [;注释] 指令助忆符体现该指令的功能,它对应一条二进制编码的机 ...
- windows使用笔记-google-chrome下载地址
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! google-chrome下载地址:https://www.google.cn/intl/zh-CN/chrome/
- Python 多线程、多进程 (三)之 线程进程对比、多进程
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...
- Dockerfile 中 RUN, CMD, ENTRYPOINT 的区别
RUN 指令:用于指定 docker build 过程中要运行的命令. 语法格式: RUN <command> 或 RUN ["<executeable>" ...
- 【代码笔记】Web-HTML-基础
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- JavaScript高级特性-数组
1. JavaScript中的数组 在C++.Java中,数组是一种高效的数据结构,随机访问性能特别好,但是局限性也特别明显,就是数组中存放的数据必须是同一类型的,而在JavaScript中,数组中的 ...
- Oracle 11g 发行版2的安装,PLSQL_Developer安装 , Oracle数据库安装失败,完全卸载,常用的命令
Oracle 11g 发行版2的安装 PLSQL_Developer安装 Oracle数据库安装失败,完全卸载oracle11g 常用的命令 Oracle 11g 发行版2的安装 1. 下载 下载地址 ...
- CRM lookup筛选
function Loadcouse() { var type; var id; retrieveRecord(Xrm.Page.getAttribute("ownerid").g ...
- matplotlib numpy scipy 的安装
一:windows 端的安装 #cmd指令 python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sym ...
- Pair Programming 2
学生-社团匹配程序 项目流程: 1. 分析讨论 2. 分工合作 3. 代码规范 4. 编码实现 5. 模块结合 6. 测试修改 7. 数据样例 8. 心得体会 9. GitHub链接 结对队友:陈文举 ...