传送门


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


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

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

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

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

Code:

#include <queue>
#include <cstdio>
#include <cctype>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define R register
#define ll long long
using namespace std;
const int N = 110000; int hd[N], nxt[N], to[N], dfn[N], low[N], scc[N], dgrV[N], dgrS[N], stck[N], instck[N], rep[N];
int n, m, cnt, tot, noedg = 1, top;
queue<int> que; template <class T> inline void read(T &x) {
x = 0;
char ch = getchar(), w = 0;
while (!isdigit(ch))
w = (ch == '-'), ch = getchar();
while (isdigit(ch))
x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
x = w ? -x : x;
return;
} inline void addEdg(int x, int y) {
nxt[++noedg] = hd[x], hd[x] = noedg, to[noedg] = y;
return;
} void tarjan(int now) {
dfn[now] = low[now] = ++cnt;
stck[++top] = now, instck[now] = 1;
for (R int i = hd[now]; i; i = nxt[i]) {
int v = to[i];
if (dfn[v]) {
if (instck[v]) low[now] = min(low[now], dfn[v]);
}
else
tarjan(v), low[now] = min(low[now], low[v]);
}
if (dfn[now] == low[now]) {
rep[++tot] = now;
while (stck[top] != now)
instck[stck[top]] = 0, scc[stck[top--]] = tot;
instck[now] = 0, scc[stck[top--]] = tot;
}
return;
} inline void del(int x) {
for (R int i = hd[x], v; i; i = nxt[i]) {
if (scc[v = to[i]] != scc[x]) {
if (!--dgrS[scc[v]]) que.push(rep[scc[v]]);
}
else if (!--dgrV[v] && v != rep[scc[v]]) que.push(v);
}
return;
} int main() {
int x, y;
read(n), read(m);
for (R int i = 1; i <= m; ++i)
read(x), read(y), addEdg(x, y);
for (R int i = 1; i <= n; ++i)
if (!dfn[i])
tarjan(i);
for (R int i = 1; i <= n; ++i)
for (R int j = hd[i], v; j; j = nxt[j])
if (scc[v = to[j]] != scc[i])
++dgrS[scc[v]];
else
++dgrV[v];
for (R int i = 1; i <= tot; ++i)
if (!dgrS[i])
que.push(rep[i]);
while (que.size()) {
if (que.size() == 1) {
cout << "! " << que.front() << endl;
return 0;
}
int a = que.front(), b;
que.pop(), b = que.front(), que.pop();
cout << "? " << a << ' ' << b << endl;
read(x);
if (x) del(b), que.push(a);
else del(a), que.push(b);
}
return 0;
}

[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. 2、Shiro的认证

    Shiro的认证流程大体可以参考下面这幅图: 但是没有接触过shiro的同学看到上面的图片也不明白,下面我们来在代码中尝试体验Shiro的认证过程: 1.新建一个SpringBoot项目项目结构如下: ...

  2. eclipse 4.32 安装 gradle

    更新网址  http://dist.springsource.com/release/TOOLS/gradle

  3. Jmeter之HTTP常用配置元件(默认、头信息和cookies)

    在进行HTTP接口的测试时,会用到部分常用的配置元件,现在简单的说明: 一.HTTP请求默认值 在测试同一个项目的HTTP请求接口时,会存在部分相同的信息,可以将这些相同的信息提取出来,使用HTTP请 ...

  4. 【汇总】Wireshark 过滤规则

    作者:Bay0net 时间:2019-07-01 14:20:09 更新: 介绍:记录使用过的 wireshark 过滤规则 0x01. 使用介绍 抓包采用 wireshark,提取特征时,要对 se ...

  5. Jvm组成以及调优

    Jvm的内存由三部分组成Eden,S0,S1,Old以及Metaspace(JDK1.8之前的Perm区)五部分组成: (图片摘自VisualVM的Visual GC插件) 抽象为三代:新生代(Ede ...

  6. 非GUI模式运行Jmeter脚本

    一.应用场景 日常测试过程中发现,在大数量并发时,jmeterGUI界面经常宕机.卡死,在这种情况下我们就需要使用命令行来执行脚本了(非GUI模式). 二.命令行模式优点 1.节约系统资源,无需启动界 ...

  7. win10在文件夹下打开powershell

    快捷键win+R,输入cmd可以直接打开终端命令行窗口 在文件夹下打开终端命令行端口: 在需要的文件夹目录下,按住shift键,在空白处右击,选择在此处打开powershell窗口,即可进行终端命令行 ...

  8. 获取使用GitHub api和Jira api Authentication的方法

    近段时间在搭建我司的用例管理平台,有如下需求: 1.需要根据项目--版本--轮次的形式来管理项目用例,用例统一保存在git工程. 2.执行用例时,如果用例执行失败,可以通过平台在Jira上提bug. ...

  9. 2.nginx配置详细说明

    Nginx配置详解 nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行 ...

  10. 深入理解java:2.2. 同步锁Synchronized及其实现原理

    同步的基本思想 为了保证共享数据在同一时刻只被一个线程使用,我们有一种很简单的实现思想,就是 在共享数据里保存一个锁 ,当没有线程访问时,锁是空的. 当有第一个线程访问时,就 在锁里保存这个线程的标识 ...