【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的长方形去填格子的空缺; 如果有填满的方案且方案 ...
随机推荐
- 数组式访问-ArrayAccess
以前对ArrayAccess不是很熟悉,现在整理下下有关ArrayAccess相关的知识,ArrayAccess接口就是提供像访问数组一样访问对象的能力的接口. 接口内容如下: ArrayAccess ...
- 设计模式之命令模式(Command )
命令模式是我们能够实现发送者和接收者之间的完全解耦,发送者是调用操作的对象,而接收者是接收请求并执行特定操作的对象.通过解耦,发送者无需了解接收者的接口.在这里,请求的含义是需要被执行的命令. 作用 ...
- Python 类的特殊成员介绍
类的成员有两种形式 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法,私有成员命名时,前两个字符是下划线. class Foo: def __init__(self, name, age ...
- 第三次web作业
em是相对长度单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸,最初是指字母M的宽度,故名em.现指的是字符宽度的倍数,用法类似百分比,如:0 ...
- vue 父子组件互相传值容易出现的报错
对于父子组件之间的互相传值,报错如下: [Vue warn]: Avoid mutating a prop directly since the value will be overwritten w ...
- web应用
实现HttpServlet的Web应用 <dependency> <groupId>javax.servlet</groupId> <artifactId&g ...
- Java:匿名类,匿名内部类
本文内容: 内部类 匿名类 首发日期 :2018-03-25 内部类: 在一个类中定义另一个类,这样定义的类称为内部类.[包含内部类的类可以称为内部类的外部类] 如果想要通过一个类来使用另一个类,可以 ...
- eclipse下载教程
Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成开发环境,如C,C++ ...
- Linux下postgresql数据库部署与配置
1.检查postgresql是否已经安装:rpm -qa | grep postgres 2.检查PostgreSQL 安装位置:rpm -qal | grep postgres 3.卸载Postgr ...
- windows10不能获取有效IP的问题
最近我的windows10系统一直不能有效获取IP地址(无论有线还是无线),但手工设置IP后又能正常上网,所以怀疑是某个服务未启动的原因. 查了一下百度,发现还真是,现将解决方案记录如下: 1.打开系 ...