传送门


题意:一个\(n\)个点的竞赛图,给出\(m\)条红色的边,其方向确定,其余边均为绿色,方向未知。你可以询问不超过\(2n\)次,每次询问一条绿色边的方向。要求找到一个点\(x\),使得\(x\)出发到任意一个点都有至少一条同色路径。\(n ,m\leq 10^5\)。可能会在交互过程中动态构造图。


考虑没有红色的边时怎么做。显然在询问过程中会形成若干棵绿色的外向树,每次询问两棵外向树的树根,将它们合并起来即可。最后剩余的点即为答案。

回到原题,发现由于红色边的存在导致有些边无法通过询问定向,但是红色边本身可以作为连通的方式。

将红色连通块缩点,发现此时任何没有红色入度的点均与上文中的绿色外向树等价,即,这些点满足可以任意询问两两之间的边,且这样的点只剩一个时即为答案。

另一个值得注意的点是,合并时被删除的点可能会有若干红色出边,此时需遍历这些边,并将新的满足条件的点加入待处理点集中。

Code:

  1. #include <queue>
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <cassert>
  5. #include <cstring>
  6. #include <iostream>
  7. #include <algorithm>
  8. #define R register
  9. #define ll long long
  10. using namespace std;
  11. const int N = 110000;
  12. int hd[N], nxt[N], to[N], dfn[N], low[N], scc[N], dgrV[N], dgrS[N], stck[N], instck[N], rep[N];
  13. int n, m, cnt, tot, noedg = 1, top;
  14. queue<int> que;
  15. template <class T> inline void read(T &x) {
  16. x = 0;
  17. char ch = getchar(), w = 0;
  18. while (!isdigit(ch))
  19. w = (ch == '-'), ch = getchar();
  20. while (isdigit(ch))
  21. x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
  22. x = w ? -x : x;
  23. return;
  24. }
  25. inline void addEdg(int x, int y) {
  26. nxt[++noedg] = hd[x], hd[x] = noedg, to[noedg] = y;
  27. return;
  28. }
  29. void tarjan(int now) {
  30. dfn[now] = low[now] = ++cnt;
  31. stck[++top] = now, instck[now] = 1;
  32. for (R int i = hd[now]; i; i = nxt[i]) {
  33. int v = to[i];
  34. if (dfn[v]) {
  35. if (instck[v]) low[now] = min(low[now], dfn[v]);
  36. }
  37. else
  38. tarjan(v), low[now] = min(low[now], low[v]);
  39. }
  40. if (dfn[now] == low[now]) {
  41. rep[++tot] = now;
  42. while (stck[top] != now)
  43. instck[stck[top]] = 0, scc[stck[top--]] = tot;
  44. instck[now] = 0, scc[stck[top--]] = tot;
  45. }
  46. return;
  47. }
  48. inline void del(int x) {
  49. for (R int i = hd[x], v; i; i = nxt[i]) {
  50. if (scc[v = to[i]] != scc[x]) {
  51. if (!--dgrS[scc[v]]) que.push(rep[scc[v]]);
  52. }
  53. else if (!--dgrV[v] && v != rep[scc[v]]) que.push(v);
  54. }
  55. return;
  56. }
  57. int main() {
  58. int x, y;
  59. read(n), read(m);
  60. for (R int i = 1; i <= m; ++i)
  61. read(x), read(y), addEdg(x, y);
  62. for (R int i = 1; i <= n; ++i)
  63. if (!dfn[i])
  64. tarjan(i);
  65. for (R int i = 1; i <= n; ++i)
  66. for (R int j = hd[i], v; j; j = nxt[j])
  67. if (scc[v = to[j]] != scc[i])
  68. ++dgrS[scc[v]];
  69. else
  70. ++dgrV[v];
  71. for (R int i = 1; i <= tot; ++i)
  72. if (!dgrS[i])
  73. que.push(rep[i]);
  74. while (que.size()) {
  75. if (que.size() == 1) {
  76. cout << "! " << que.front() << endl;
  77. return 0;
  78. }
  79. int a = que.front(), b;
  80. que.pop(), b = que.front(), que.pop();
  81. cout << "? " << a << ' ' << b << endl;
  82. read(x);
  83. if (x) del(b), que.push(a);
  84. else del(a), que.push(b);
  85. }
  86. return 0;
  87. }

[CF1142E] Pink Floyd的更多相关文章

  1. Linux 利器- Python 脚本编程入门(一)

    导读 众所周知,系统管理员需要精通一门脚本语言,而且招聘机构列出的职位需求上也会这么写.大多数人会认为 Bash (或者其他的 shell 语言)用起来很方便,但一些强大的语言(比如 Python)会 ...

  2. 张小龙《微信背后的产品观》之PPT完整文字版

    微信回顾 433天,一亿用户 成为移动互联网的新入口 启动(2010年11月19日) 用户数突破1亿 1.0 1月26日 2.0 5月10日 语音对讲 2.5 8月3日 查看那附近的人 3.0 10月 ...

  3. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  4. 【Unity3D插件】在Unity中读写文件数据:LitJSON快速教程

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 介绍 JSON是一个简单的,但功能强大的序列 ...

  5. LitJSON使用

    地址:http://lbv.github.io/litjson/docs/quickstart.html LitJSON Quickstart Guide Introduction Quick Sta ...

  6. Unity 学习Json篇

    介绍 JSON是一个简单的,但功能强大的序列化数据格式.它定义了简单的类型,如布尔,数(int和float)和字符串,和几个数据结构:list和dictionnary.可以在http://JSON.o ...

  7. ASP.NET MVC - Entity Framework

    ASP.NET MVC - Entity Framework 实体关系 关系是某个实体(表)的一条记录对应于另一个实体(表)的一条或多条记录. 一对多关系 单方面的包含关系称为一对多,而一对多和一对一 ...

  8. Codeforces Round #549 (Div. 1) 题解

    link 前几天补完了某一场很早以前的div1,突然想来更博客,于是就有了这篇文章 A The Beatles 显然若起点和第一次到达的位置距离为 d ,那么经过的不同站点数为 $\frac{nk}{ ...

  9. Create XML Files Out Of SQL Server With SSIS And FOR XML Syntax

    So you want to spit out some XML from SQL Server into a file, how can you do that? There are a coupl ...

随机推荐

  1. 文件的权利和sudoers中规定的权限哪个更大?

    文件的权利和sudoers中规定的权限哪个更大? 当然是文件的权限更大!!! 这也是linux的 更安全的根本所在! 就是它的每一个文件都有严格的 rwxr--r-- 权限规定. 只有文件权限规定了的 ...

  2. java利用zip解压slpk文件

    public static void main(String[] args) { File file = new File("C:\\Users\\Administrator\\Deskto ...

  3. 【python3】 抓取异常信息try/except

    注意:老版本的Python,except语句写作"except Exception, e",Python 2.6后应写作"except Exception as e&qu ...

  4. Delphi XE2 之 FireMonkey 入门(31) - 数据绑定: 绑定数据库

    Delphi XE2 之 FireMonkey 入门(31) - 数据绑定: 绑定数据库 一.全设计时操作: 先在窗体上放置控件: DataSource1    : TDataSource; Clie ...

  5. Django开启https(不用nginx)

    首先安装需要用到的包 pip install django-extensions pip install django-werkzeug-debugger-runserver pip install ...

  6. window.screenLeft&&window.screenTop&&window.screenX&&window.screenY

    http://blog.sina.com.cn/s/blog_14e2a237b0102w4i0.html window.screenLeft&&window.screenTop&am ...

  7. if you wanna the rainbow, you have to deal with the rain.

    bulk. n. 大量 reluctant. adj. 不情愿的 terrorist. n. 恐怖分子 recognition. n. 认出 tout.v. 兜售 conceal.v. 隐藏 dras ...

  8. diff patch比较文件打补丁

    比较文件将结果保存到patch文件:diff -u test1.txt test2.txt > patchfile test1.txt应用patch文件,并备份(test1.txt.orig): ...

  9. MySQL-快速入门(1)基本数据库、表操作语句

    1.创建数据库 create database db_name;show create database db_name\G; //查看数据创建语句show databases; //查看当前创建的数 ...

  10. .Net Core - 使用Supervisor进行托管部署

    环境 CentOS 7 x64,详见 安装CentOS7虚拟机 .Net Core 2.1.801 详见 CentOS 7 下安装.NET Core SDK 2.1 ftp  详见  CentOS7 ...