problem

洛谷链接

solution

看到这个 20%20\%20% 的特殊性质,脑海里第一个就想到了随机化算法。已经PTSD了着实上头

如果本题只是随便求一个 interesting\text{interesting}interesting 的点,那就非常简单了。

随机化一个点,检查这个点是否满足 interesting\text{interesting}interesting 的限制即可。

如果判断一个点是否是 interesting\text{interesting}interesting 的点?以该点为根建立 dfs-tree。如果只有树边和返祖边,没有一条横叉边,那么这个点就是“有趣点”。

一次判断的复杂度是 O(n)O(n)O(n) 的。

执行 min⁡(100,n)\min(100,n)min(100,n) 次,正确率就高达 1−(45)1001-(\frac{4}{5})^{100}1−(54​)100。

虽然很简单,但是本题的正解就是建立在这种随机的基础上的。

我们不能求出所有点,但是可以快速通过随机求出一个 interesting\text{interesting}interesting 点,记为 ididid。

以 ididid 为根,建立 dfs-tree ,那么这棵树是没有横叉边的。

考虑能否在这棵树上求出所有的 interesting\text{interesting}interesting 点。

显然是可以的,需要用到几个小性质。

定理1 树上一个非根节点 uuu 的子树内至少会有一条连向子树外的边(跨过 uuu),即返祖边。

这是显然的,因为题目保证点两两之间是可以互达的。

定理2 如果树上一个非根节点 uuu 的子树内有不止一条连向子树外的边,则该点不是 interesting\text{interesting}interesting 点。

  • 如果两条返祖边都指向同一个祖先,也就意味着 uuu 有两条到达这个祖先的路径。
  • 如果两条返祖边指向不同的祖先,但这两组先之间也存在祖先后辈关系,相当于到某个辈分较小的祖先也有两条路径。

定理3 如果树上一个非根节点 uuu 的子树内只有一条连向子树外的边,uuu 是“有趣点” 当且仅当这条返祖边连向的祖先也是“有趣点”。

这也是显然的。uuu 到这个祖先是一条简单路径,祖先不是“有趣点”就意味着祖先到某个点有不止一条路径。传递过来等价于 uuu 到某个点也有不止一条路径。

请时刻注意,根 ididid 一定是“有趣点”,树一定没有横叉边。

所以我们可以通过 dfs 来完成筛选。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 100005
bool flag;
int T, n, m;
vector < int > ans, G[maxn];
int dep[maxn], low[maxn], cnt[maxn], vis[maxn];
bool bad[maxn];void dfs_good( int u ) {if( ! flag ) return;vis[u] = 1;for( int v : G[u] )if( ! vis[v] ) dfs_good( v );else if( vis[v] == 2 ) { flag = 0; return; }vis[u] = 2;
}int dfs( int u ) {vis[u] = 1, low[u] = u;for( int v : G[u] )if( ! vis[v] ) {dep[v] = dep[u] + 1;cnt[u] += dfs( v );if( dep[low[v]] < dep[low[u]] ) low[u] = low[v];}
//为什么选深度最小的点呢?因为这个点的辈分最大 能跨过这个点的返祖边对应的点越少else {cnt[u] ++, cnt[v] --;//因为之前是直接把后代的返祖边加上来的,但是这些返祖边对于这个祖先而言还是后代之间的连边 并未跨过这个祖先if( dep[v] < dep[low[u]] ) low[u] = v;}if( cnt[u] > 1 ) bad[u] = 1;return cnt[u];
}void dfs_bad( int u ) {vis[u] = 1;if( bad[low[u]] ) bad[u] = 1;for( int v : G[u] ) if( ! vis[v] ) dfs_bad( v );
}int main() {mt19937 wwl(time(0));scanf( "%d", &T );while( T -- ) {ans.clear();for( int i = 1;i <= n;i ++ ) {G[i].clear();low[i] = bad[i] = dep[i] = cnt[i] = vis[i] = 0;}scanf( "%d %d", &n, &m );for( int i = 1, u, v;i <= m;i ++ ) {scanf( "%d %d", &u, &v );G[u].push_back( v );}uniform_int_distribution < int > range( 1, n );int id = -1;for( int t = 1;t <= 100;t ++ ) {flag = 1;for( int i = 1;i <= n;i ++ ) vis[i] = 0;id = range( wwl );dfs_good( id );if( flag ) break;}if( ! flag ) { puts( "-1" ); continue; }for( int i = 1;i <= n;i ++ ) vis[i] = 0;dfs( id );for( int i = 1;i <= n;i ++ ) vis[i] = 0;dfs_bad( id );for( int i = 1;i <= n;i ++ )if( ! bad[i] ) ans.push_back( i );sort( ans.begin(), ans.end() );if( ans.size() * 5 < n ) printf( "-1" );else for( int i : ans ) printf( "%d ", i );printf( "\n" );}return 0;
}

CodeForces 1361E James and the Chase(dfs + 结论)相关推荐

  1. codeforces E. Jamie and Tree LCA+dfs序+线段树

    题解: 写起来还稍微有点麻烦. dfs序+线段树可以维护子树的整体修改和查询. 因此,这道题我们要往子树上靠. 我们首先从1号点进行dfs遍历,顺便求出点的dfs序和深度,然后我们采用倍增的思想,可以 ...

  2. Codeforces Codeforces Round #383 (Div. 2) E (DFS染色)

    题目链接:http://codeforces.com/contest/742/problem/E 题意: 有一个环形的桌子,一共有n对情侣,2n个人,一共有两种菜. 现在让你输出一种方案,满足以下要求 ...

  3. PTA 5-10 Saving James Bond-Easy (25) - 图 - DFS

    题目:http://pta.patest.cn/pta/test/16/exam/4/question/672 PTA - Data Structures and Algorithms (Englis ...

  4. codeforces 580C Kefa and Park(DFS)

    题目链接:http://codeforces.com/contest/580/problem/C #include<cstdio> #include<vector> #incl ...

  5. CodeForces - 1139C Edgy Trees (快速幂+dfs)

    题目:CodeForces - 1139C 题意:一个n个节点的无向图,有n-1条边每条边是黑色或者红色,现在统计包含k个点(不需要连续)的路中至少有1条黑边的路径数目 分析:总共有n^k条路径,将所 ...

  6. CodeForces - 11C How Many Squares?【DFS】

    题目链接:https://codeforces.com/contest/11/problem/C 来自洛谷题解的做法,先找第一类正方形,再找第二类正方形,dfs找联通块并全部清除,判断1的数量是否构成 ...

  7. CodeForces #369 div2 D Directed Roads DFS

    题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...

  8. Codeforces 930 A. Peculiar apple-tree (dfs)

    题目: 代码: #include <bits\stdc++.h> using namespace std;int b[100010]; //b[i]表示距离1号花絮i步的花絮的个数 map ...

  9. CodeForces - 1341F Nastya and Time Machine(dfs+构造)

    题目链接:点击查看 题目大意:给出一棵树,现在要求从点1出发遍历所有的结点一遍后再回到点1,额外给出一个时光机,可以到某个节点的任意时刻,需要满足的条件如下: 初始时在节点 1 ,时间为 0 每次操作 ...

最新文章

  1. c语言字符串 s,c – printf格式字符串中“% – *.* s”的含义是什么
  2. FreeBSD Ports加速的方法
  3. 跟我做CVS版本管理试验
  4. C++ namespace 命名空间
  5. iview 下拉select样式_Vue.js相关:iview实现select tree树形下拉框的示例代码
  6. java 判断域密码到期提醒,Exchange Server 2010下,检测用户密码到期通知提醒脚本...
  7. linux日志服务器配置在哪个文件,Linux中日志的基本配置(syslog)
  8. L--弹出层js实例
  9. r7 2700X装Linux,R7 2700X大战i7 8700K:谁才是游戏玩家的菜?
  10. 在线博客系统——注册
  11. 硕士学位论文多级标题编号与图表编号
  12. SOFA Weekly | SOFA 社区元旦快乐,MOSN 荣获 2020 中国优秀开源项目
  13. The server encountered an unexpected condition that prevented it from fulfilling the request
  14. Ubuntu14.10 更新源
  15. linux写日历脚本,shell脚本实现日历的屏幕控制
  16. ROS系统MoveIt玩转双臂机器人系列(三)--利用controller控制实际机器人
  17. SOPC设计02——硬件系统开发流程
  18. 蛊惑者马云发家史(曾推毛氏运动唐僧团队)一
  19. linux docker安装nginx且测试elasticsearch分词
  20. 33220a 编程C语言,基于AT89C51单片机的数字式波形发生器(非常完整).doc

热门文章

  1. 天赋差的程序员,难道就只能半途而废吗?
  2. 都说Python库千千万,这几个你认识不?
  3. 全景图解高铁数据,谁是最有潜力的高铁城市?
  4. 从头到尾彻底理解傅里叶变换算法(下)
  5. linux 压缩成bz2,linux 将文件压缩成bz2格式 命令:bzip2
  6. python进阶之学习笔记_干货 | Python进阶系列之学习笔记(四)
  7. 初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
  8. java 声明变量构成_Java—变量
  9. 2019年第十届蓝桥杯国赛B组试题B-质数拆分-01背包问题+素数筛选
  10. [蓝桥杯][2013年第四届真题]核桃的数量-枚举(水题)