Solution -「CF 1361E」James and the Chase
\(\mathcal{Description}\)
Link.
给定 \(n\) 个点 \(m\) 条边的有向弱连通图。称一个点是“好点”当且仅当从该点出发,不存在到同一点的两条不同简单路径。求出所有好点,但若好点个数少于 \(n \times 20\%\),仅输出 -1。
多测,\(n,\sum_{}^{} n \le10^5\),\(m,\sum_{}^{} m\le2\times10^5\)。
\(\mathcal{Solution}\)
先来想一想如何判断某个点 \(r\) 是好点。以 \(r\) 为根建出任意一棵外向生成树,不难发现 \(r\) 是好点,当且仅当树外不存在横叉边(有向 DFS 树是可能存在横叉边的)。
假设我们已经得到了一点 \(r\) 为好点,如何判断出其他点是否是好点呢?考虑在刚才那棵外向生成树上的某一非根结点 \(u\),若从 \(u\) 子树内向 \(u\) 的祖先的返祖边多于一条,就显然不合法,否则若 \(u\) 能到达最高的祖先合法,\(u\) 也必然合法。
最后一个问题,怎么找到一个 \(r\) 呢?考虑到 \(20\%\) 的限制,随机 \(100\) 个点进行好点测验,如果都不是好点直接输出 -1。错误率为 \(\left( \frac{4}{5} \right)^{100}\),非常可观。
复杂度 \(\mathcal O(100\sum_{}^{} n)\)。
\(\mathcal{Code}\)
/* Clearink */
#include <cstdio>
#include <random>
inline int rint () {
int x = 0, f = 1; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x * f;
}
template<typename Tp>
inline void wint ( Tp x ) {
if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
}
const int MAXN = 1e5, MAXM = 2e5;
int n, m, ecnt, head[MAXN + 5], vtag[MAXN + 5], upc[MAXN + 5], top[MAXN + 5];
bool bad[MAXN + 5];
std::mt19937 rnd ( 20050913 );
struct Edge { int to, nxt; } graph[MAXM + 5];
inline void link ( const int s, const int t ) {
graph[++ ecnt] = { t, head[s] };
head[s] = ecnt;
}
inline bool check ( const int u ) {
vtag[u] = 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( !vtag[v = graph[i].to] ) {
if ( !check ( v ) ) return false;
} else if ( vtag[v] == 2 ) {
return false;
}
}
vtag[u] = 2;
return true;
}
inline void mark ( const int u ) {
top[u] = u;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( !vtag[v = graph[i].to] ) {
vtag[v] = vtag[u] + 1;
mark ( v ), upc[u] += upc[v];
if ( vtag[top[v]] < vtag[top[u]] ) top[u] = top[v];
} else {
++ upc[u], -- upc[v];
if ( vtag[v] < vtag[top[u]] ) top[u] = v;
}
}
}
inline int spread ( const int u ) {
vtag[u] = 1, bad[u] = upc[u] > 1;
int ret = !( bad[u] |= bad[top[u]] );
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( !vtag[v = graph[i].to] ) {
ret += spread ( v );
}
}
return ret;
}
inline void clear () {
ecnt = 0;
for ( int i = 1; i <= n; ++ i ) {
head[i] = vtag[i] = upc[i] = top[i] = bad[i] = 0;
}
}
int main () {
for ( int T = rint (); T --; ) {
clear ();
n = rint (), m = rint ();
for ( int i = 1, u, v; i <= m; ++ i ) {
u = rint (), v = rint ();
link ( u, v );
}
int rt = 0;
for ( int i = 1; i <= 100 && !rt; ++ i ) {
int u = rnd () % n + 1;
for ( int i = 1; i <= n; ++ i ) vtag[i] = 0;
if ( check ( u ) ) rt = u;
}
if ( !rt ) { puts ( "-1" ); continue; }
for ( int i = 1; i <= n; ++ i ) vtag[i] = 0;
vtag[rt] = 1, mark ( rt );
for ( int i = 1; i <= n; ++ i ) vtag[i] = 0;
int cnt = spread ( rt );
if ( cnt * 5 < n ) { puts ( "-1" ); continue; }
for ( int i = 1, f = 0; i <= n; ++ i ) {
if ( !bad[i] ) {
if ( f ) putchar ( ' ' );
f = 1, printf ( "%d", i );
}
}
putchar ( '\n' );
}
return 0;
}
\(\mathcal{Details}\)
这种随机乱搞题得放开点脑洞啊,看到这种 \(20\%\) 之类的奇怪限制就可以往这方面想啦。
Solution -「CF 1361E」James and the Chase的更多相关文章
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
- Solution -「CF 1622F」Quadratic Set
\(\mathscr{Description}\) Link. 求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...
- Solution -「CF 923F」Public Service
\(\mathscr{Description}\) Link. 给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...
- Solution -「CF 923E」Perpetual Subtraction
\(\mathcal{Description}\) Link. 有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...
- Solution -「CF 1586F」Defender of Childhood Dreams
\(\mathcal{Description}\) Link. 定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...
- Solution -「CF 1237E」Balanced Binary Search Trees
\(\mathcal{Description}\) Link. 定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...
- Solution -「CF 623E」Transforming Sequence
题目 题意简述 link. 有一个 \(n\) 个元素的集合,你需要进行 \(m\) 次操作.每次操作选择集合的一个非空子集,要求该集合不是已选集合的并的子集.求操作的方案数,对 \(10^9 ...
- Solution -「CF 1023F」Mobile Phone Network
\(\mathcal{Description}\) Link. 有一个 \(n\) 个结点的图,并给定 \(m_1\) 条无向带权黑边,\(m_2\) 条无向无权白边.你需要为每条白边指定边权 ...
- Solution -「CF 599E」Sandy and Nuts
\(\mathcal{Description}\) Link. 指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...
随机推荐
- java 多态 总结
1.前言 引用教科书解释: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 通俗来说: 总结:多态的抽象类与接口有点相似: 父类不需要具体实现方 ...
- centos7 配置rm命令失效。
之前写过一篇alias别名的方法,但这个方法配置rm命令在重启后就无效了.而且重启后得输入source alias_test.sh.才可以 centos7 alias别名永久生效 原因是:root用户 ...
- Scrapy的Item_loader机制详解
一.ItemLoader与Item的区别 ItemLoader是负责数据的收集.处理.填充,item仅仅是承载了数据本身 数据的收集.处理.填充归功于item loader中两个重要组件: 输入处理i ...
- redis 主从复制实现
Redis 主从复制的实现 安装redis 修改redis的配置文件 redis.conf ②开启daemonize yes ③Pid文件名字 ④指定端口 ⑤Log文件名字 ⑥Dump.rdb名字 在 ...
- C# 开源一个基于 yarp 的 API 网关 Demo,支持绑定 Kubernetes Service
关于 Neting 刚开始的时候是打算使用微软官方的 Yarp 库,实现一个 API 网关,后面发现坑比较多,弄起来比较麻烦,就放弃了.目前写完了查看 Kubernetes Service 信息.创建 ...
- 大型站点TCP/IP协议优化
作为一个DAU上百万或千万的站点,不仅仅需要做好网站应用程序.数据库的优化,还应从TCP/IP协议层去进行相关的优化: 在我的工作中,曾使用到了以下的几种基本的优化方式: 增大最大连接数 在Linux ...
- 【Java】GUI编程
GUI编程 前言 某koukou老师的任务罢了,好在狂神老师居然有GUI的课,只能说是有救星了. [狂神说Java]GUI编程入门到游戏实战 最好笑的是,老师要求掌握的居然是14年的知识,就连狂神在上 ...
- Javascript中字符串常用方法
JavaScript字符串常用方法 (1)获取相应位置的字符(charAt()) var str="你好,小小鸟!" var s=str.charAt(1) //获取到索引为1的字 ...
- UML 有关类图知识及类间关系
原文链接:https://blog.csdn.net/mj_ww/article/details/53020346 1. 类的含义 类图(Class diagram)显示了系统的静态结构,而系统的静态 ...
- i-Urban Renovation使用3D Tiles可视化鸟取县Munakata建筑状态
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 日本的鸟取县,使用i-Urban Renovation appl ...