HCW 19 Team Round (ICPC format) B. Beggin' For A Node(树的重心,交互题)
B. Beggin' For A Node
time limit per test2.0 s
memory limit per test256 MB
inputstandard input
outputstandard output
This is an interactive problem
Low_ has a beautiful tree, which he keeps very carefully. A tree is a tree, but mathematically, it could be modeled as an indirect connected graph with no cycles. Suppose low_'s tree has n nodes and n−1 edges.
S_e_o is low_'s friend, and he has been attracted to the Codeforces golden secret for a long time. He does not want to hurt his friend by taking it illegally, especially from his beloved tree, so S_e_o comes up with a devious plan. He hides the golden secret in a node of low_'s favorite tree and challenges him to find that node by interacting with an A.I bot which was created by another hacker named b21. There are two types of question that low_ could beg for:
"?1u": The bot will return number of edges on the simple path from node u to the hidden node.
"?2u": The bot will return the second node on the simple path from node u to the hidden node. If this type of query is asked for the hidden node by luck, the bot will return 0.
Low_ does not want his friend to read his own secret to become master at Codeforces, so he has to be quick. Please help him, and remember to be quick by only asking no more than 36 queries.
Input
The first line contains an integer n (1≤n≤200000).
The next n−1 lines, each contains two integers u and v (1≤u,v≤n) denotes that there's an edge connects u and v in the tree.
Interaction
You can make queries of type "? T u" to the robot. T is either 1 or 2, and 1≤u≤n. The description for query is stated in the problem legend.
After the query read its result as an integer. If you read −1, that means your query is in the wrong format, or you have exceeded 36 queries. Exit the program immediately to get the verdict "Wrong answer". If you don't, you might get an arbitrary verdicts.
When you find out the array, print "!" followed by a space and an integer denotes your answer. This is not counted as a query, but you only have one guess. If you failed to get the answer right, your verdict will be "Wrong answer".
After printing any query do not forget to output end of line and flush the output. Otherwise you will get Idleness limit exceeded. To do this, use:
fflush(stdout) or cout.flush() in C++;
System.out.flush() in Java;
flush(output) in Pascal;
stdout.flush() in Python.
Example
inputCopy
7
2 1
2 4
3 5
6 2
1 3
2 7
1
3
0
outputCopy
? 2 2
? 1 6
? 1 3
! 3
题意:
自行读题。
思路:
我们设隐藏的节点为X。
树的重心,也叫树的质心。对于一棵树来说,删去该树的重心后,所有的子树的大小不会超过原树大小的二分之一
我们利用这个性质,我们先找到整个树的重心Y,然后问其到X的第二个节点是哪个。假设是U,
然后断开U和Y的连接,这样剩下的包含U这一块的部分肯定是含有X节点的。并且节点个数小于等于之前的二分之一,
继续重复上面行为,直至回答0,即找到了节点X。
因为我们每一次递归节点个数都减少一半,那么我们最多20次左右即可找到X节点,因为 2^20>=2e5
这里断开连接并不是删除边,而是用了一个数组bool cut[i] 表示第i个节点是否被隔开,如果是dfs就不访问即可。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 200010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
std::vector<int> son[maxn];
int n;
int cntnum;
int cntson[maxn];
bool cut[maxn];
int ask(int op, int x)
{
cout << "? " << op << " " << x << endl;
int res;
cin >> res;
return res;
}
int center(int x, int pre)// 求剩下树的部分的重心
{
for (auto y : son[x])
{
if (y != pre && !cut[y] && cntson[y] > cntnum / 2)
{
return center(y, x);
}
}
return x;
}
void predfs(int x, int pre)// 处理出剩下树中以x为根的子树节点个数
{
cntson[x] = 1;
for (auto y : son[x])
{
if (y != pre && !cut[y])
{
predfs(y, x);
cntson[x] += cntson[y];
}
}
}
void solve(int x)
{
predfs(x, x);
cntnum = cntson[x];// 当前剩余的节点个数
int NEXT;
x = center(x, x);
NEXT = ask(2, x);
if (!NEXT)
{
cout << "! " << x << endl;
} else
{
cut[x] = 1;// 相当于隔断next 与 x连接的边。
solve(NEXT);
}
}
int main()
{
scanf("%d", &n);
repd(i, 2, n)
{
int u, v;
scanf("%d %d", &u, &v);
son[u].push_back(v);
son[v].push_back(u);
}
solve(1);
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
HCW 19 Team Round (ICPC format) B. Beggin' For A Node(树的重心,交互题)的更多相关文章
- HCW 19 Team Round (ICPC format) H Houston, Are You There?(极角排序)
题目链接:http://codeforces.com/gym/102279/problem/H 大致题意: 你在一个定点,你有个长度为R的钩子,有n个东西在其他点处,问你能勾到的东西的数量是多少? 思 ...
- Codeforces Round #359 (Div. 2) D. Kay and Snowflake 树的重心
题目链接: 题目 D. Kay and Snowflake time limit per test 3 seconds memory limit per test 256 megabytes inpu ...
- AIM Tech Round 4 (Div. 1) C - Upgrading Tree 构造 + 树的重心
C - Upgrading Tree 我发现我构造题好弱啊啊啊. 很明显能想到先找到重心, 然后我们的目标就是把所有点接到重心的儿子上,让重心的儿子子树变成菊花图, 这个先把重心到儿子的边连到 i , ...
- Codeforces Round #427 (Div. 2) E. The penguin's game (交互题,二进制分组)
E. The penguin's game time limit per test: 1 second memory limit per test: 256 megabytes input: stan ...
- 2017ACM暑期多校联合训练 - Team 4 1004 HDU 6070 Dirt Ratio (线段树)
题目链接 Problem Description In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the foll ...
- Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并
D. Developing Game Pavel is going to make a game of his dream. However, he knows that he can't mak ...
- Bestcoder round #65 && hdu 5592 ZYB's Premutation 线段树
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...
- Educational Codeforces Round 6 E. New Year Tree dfs+线段树
题目链接:http://codeforces.com/contest/620/problem/E E. New Year Tree time limit per test 3 seconds memo ...
- 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
随机推荐
- Idea Debug多线程不进断点问题处理
Idea也会使我狼狈不堪,Eclipse下约定成俗,却非Idea的默认规则. 比如 DEBUG多个线程时,Idea的默认设定就会遇到断点不能进入的问题. 解决的方法: 点击DEBUF框下的双红点(Vi ...
- Jconsole、JvisualVM无法连接Tomcat服务
转载自:https://blog.csdn.net/qq_27790011/article/details/88799587 打开TomcatXw.exe找到java选项卡,添加以下参数 -Dcom. ...
- jQuery页面加载完毕事件及jQuery与JavaScript的比较
1.jQuery概述 jQuery是一个JavaScript库,它集成了JavaScript.DOM.CSS和Ajax,简化了JavaScript编程,提倡write less, do more. 2 ...
- Python之异常处理合集
PermissionError: [Errno 13] Permission denied open(filePath)中的filePath是一目录路径,而非目录路径 先前打开的file文件对象未被关 ...
- pthon基础知识(索引、切片、序列相加、乘法、检查元素是否是序列成员、计算序列长度、最大最小值)
序列 数据存储方式 数据结构 python 列表.元组.字典.集合.字符串 序列: 一块用于存放多个值的连续内存空间,并且按一定顺序排列,可以通过索引取值 索引(编号): 索引可以是负数 从左到 ...
- Django-ORM之聚合和分组查询、F和Q查询、事务
聚合查询 聚合对查询的结果进行一步的计算加工. aggregate()是QuerySet 的一个终止子句 ,他的作用是,返回一个包含一些键值对的字典.键的名称是聚合值的标识符,值是计算出来的聚合值.键 ...
- 通俗易懂的lambda表达式,不懂来找我!
lambda是Python编程语言中使用频率较高的一个关键字.那么,什么是lambda?它有哪些用法?网上的文章汗牛充栋,可是把这个讲透的文章却不多.这里,我们通过阅读各方资料,总结了关于Python ...
- nginx集群+mysql数据同步
mysql集群配置在网站负载均衡中是必不可少的: 首先说下我个人准备的负载均衡方式: 1.通过nginx方向代理来将服务器压力分散到各个服务器上: 2.每个服务器中代码逻辑一样: 3.通过使用redi ...
- 关于Linux文本处理“三剑客”的一些小操作。
Linux文本处理“三剑客”,即grep.sed.awk,这是Linux中最核心 的3个命令. 一.首先做个简单的介绍: 1.awk:linux三剑客老大,过滤,输出内容,一门语言.NR代表行号. 2 ...
- 阿里云Open API自动化脚本—ECS公网IP转化弹性公网IP
1.OpenAPI Explorer 记录一下使用阿里云 Open API 自动化/脚本化 “ECS 公网 IP 转化弹性公网 IP”的实现 全过程.原博客地址:https://www.markedi ...