题面翻译
Sigma 和 Sugim在玩一个游戏。
给你两棵树,初始Sigma站在一棵树的编号为x的节点上,Sugim站在另一棵树的编号为y的节点上。Sigma和Sugim轮流行动(第一轮Sigma行动,第二轮Sugim行动),每次行动他们会移动自己所在树的相邻节点上。如果某次行动过后他们站在相同编号的节点上,则游戏结束。Sigma想让游戏尽可能持久,Sugim想让游戏尽快结束。问游戏会在第几轮行动后结束,如果不会结束则输出-1。

思路
如果你知道如何判-1,这题就会迎刃而解。
同时你只要大力猜结论,你也可以手撕此题。
然后我们就想啊想,想到了一个模糊的性质:如果Sigma从某个点到某另一个点的最短距离小于Sugim对应点之间的最短距离,而且这两点在两棵树上的对应路径之间不存在相同的点,那Sigma不是可以来回移动,而Sugim总是抓不到他?哦对,Sigma还得在Sugim到这两点中一点之前先行到达才行。那这么说,这个路径上的每条边貌似也满足性质?
于是,你再仔细想想,就会得到一个结论:设Sigma所在树边集为E1,sugim所在树边集为E2,dis1(a,b)表示a,b在第一棵树上的距离,dis2(a,b)表示a,b在第二棵树上的距离,输出-1的情况当且仅当存在某条边\(\in\)E1,设这条边两端点为u和v,Sigma能在Sugim到达之前到达这两点中一点,且\(|dis2(u,v)|> 2\)。
那游戏总会结束怎么办?那我们总得在Sigma能提前到的点中选一个作为游戏结束点吧。对了,那就选一个点u满足dis2(y,u)是最大的吧。那么我们还可以在游戏快结束时再挣扎一下吗(向左右移动),但是既然所有所有在第一棵树上相邻的点在第二棵树上的距离都小于等于
2,那移动也没有什么意义了。
然后你就A掉了此题。
哦对了,如何判断Sigma能否抢先到达这个点也很简单,只需满足Sigma到这个点这一路上每个点都符合dis1(u,x)<dis2(u,y)即可。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=2e5;
int n,x,y,tot;
int pre[maxn*4+8],son[maxn*4+8];
bool can[maxn+8];
queue<int>st;int read()
{int x=0,f=1;char ch=getchar();for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*f;
}struct Tree
{int now[maxn+8],dep[maxn+8],f[maxn+8][20];void add(int u,int v){pre[++tot]=now[u];now[u]=tot;son[tot]=v;}void build(int x){dep[x]=dep[f[x][0]]+1;for (int i=1;i<=log(dep[x])/log(2);i++) f[x][i]=f[f[x][i-1]][i-1];for (int p=now[x];p;p=pre[p]){int child=son[p];if (f[x][0]==child) continue;f[child][0]=x;build(child);}}int Get_Lca(int x,int y){if (dep[x]<dep[y]) swap(x,y);for (int i=log(dep[x])/log(2);~i;i--)if (dep[f[x][i]]>=dep[y]) x=f[x][i];if (x==y) return x;for (int i=log(dep[x])/log(2);~i;i--)if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];return f[x][0];}int Get_Dis(int x,int y){return dep[x]+dep[y]-dep[Get_Lca(x,y)]*2;}
}T1,T2;void solve()
{//for (int i=1;i<=n;i++) printf("%d ",can[i]);puts("");int ans=0;for (int i=1;i<=n;i++)if (can[i]){ans=max(ans,T2.dep[i]-1);for (int p=T1.now[i];p;p=pre[p]){int child=son[p];if (T2.Get_Dis(child,i)>2){puts("-1");exit(0);}}}printf("%d\n",ans*2);
}void prepare()
{can[x]=1;st.push(x);while(!st.empty()){int x=st.front();st.pop();for (int p=T1.now[x];p;p=pre[p]){int child=son[p];if (can[child]) continue;if (T1.dep[child]<T2.dep[child]) can[child]=1,st.push(child);}}
}int main()
{n=read(),x=read(),y=read();if (x==y){puts("0");return 0;}for (int i=1;i<n;i++){int u=read(),v=read();T1.add(u,v),T1.add(v,u);}for (int i=1;i<n;i++){int u=read(),v=read();T2.add(u,v),T2.add(v,u);}T1.build(x),T2.build(y);prepare();solve();return 0;
}

转载于:https://www.cnblogs.com/Alseo_Roplyer/p/10177489.html

AGC005_E Sugigma The Showdown相关推荐

  1. AtCoder AGC005E Sugigma: The Showdown (博弈论)

    题目链接 https://atcoder.jp/contests/agc005/tasks/agc005_e 题解 完了真的啥都不会了-- 首先,显然如果某条A树的边对应B树上的距离大于等于\(3\) ...

  2. 【AtCoder】AGC005

    AGC005 A - STring 用一个栈,如果遇到S就弹入,如果遇到T栈里有S就弹出栈顶,否则T在最后的串里,最后计算出的T和栈里剩的S就是答案 #include <bits/stdc++. ...

  3. Atcoder Grand Contest 005 题解

    A - STring 用一个栈模拟即可. //waz #include <bits/stdc++.h>using namespace std;#define mp make_pair #d ...

  4. (组合)Binomial Showdown

    求组合数 Description In how many ways can you choose k elements out of n elements, not taking order into ...

  5. javascript官方文档_基于Javascript编写的开源Markdown和HTML相互转换器——showdown

    介绍 showdown是一个基于Javascript编写的开源Markdown和HTML相互转换器,showdown可以用在客户端(浏览器)或者服务端(nodejs).shodown还支持原始规范中未 ...

  6. Cloud Hosted Notebook Showdown(云托管笔记本)

    Cloud Hosted Notebook Showdown 什么是云托管笔记本? 本地笔记本的问题 Enter Hosted Notebooks Colab vs Studio Lab 硬件 可共享 ...

  7. showdown.js记录

    2019独角兽企业重金招聘Python工程师标准>>> showdown.js是一个javascript环境下markdown语法解释工具. new Showdown.convert ...

  8. Asset Bundles vs. Resources: A Memory Showdown

    Asset Bundles vs. Resources: A Memory Showdown https://blogs.unity3d.com/cn/2017/04/12/asset-bundles ...

  9. (组合数学3.1.2.1)POJ 2249 Binomial Showdown(排列组合公式的实现)

    /** POJ_2249.cpp** Created on: 2013年10月8日* Author: Administrator*/#include <iostream> #include ...

  10. POJ1555 ZOJ1720 UVA392 UVALive5309 Polynomial Showdown题解

    代码来源:DeathYmz AC的C++语言程序如下: #include<iostream> #include<cstdio> #include<cstring> ...

最新文章

  1. 2019 浙江大学 计算机 科目,2019考研大纲:浙江大学2019年《计算机学科专业基础综合》(单考)(科目代码907)...
  2. mysql查询出来的数据用连接_mysql – 使用查询从连接的表中检索数据
  3. 嵌入式、快速人脸算法库Vision.Face SDK开放下载!已经商用检验
  4. java中showconfirmdialog_Java实现超市管理系统(含数据库)
  5. NUMA - Non Uniform Memory Architecture 非统一内存架构
  6. javascript正则表达式验证IP,URL
  7. 通过CVE-2017-17215学习路由器漏洞分析,从入坑到放弃
  8. Hr人力资源管理系统怎样给企业创造价值
  9. keil5破解(备忘,有需要的可以下载)
  10. uni-app关于tabBar配置
  11. java zip解压抛出异常,java – ZipFile抛出错误,但ZipInputStream能够解压缩归档
  12. oracle左连接查询去重,左连接去重(objec)
  13. matlab 删除workspace,MATLAB命令中清空workspace的是
  14. Python爬虫+简易词云的制作
  15. 水下动作捕捉的两种实现方式
  16. 使用bmeps将JPG PNG格式图片转EPS格式
  17. 使用爬虫抓取淘宝商品数据
  18. java 支付宝回调返回值,支付宝APP支付Java回调具体步骤
  19. C语言的取反操作(15)
  20. MATLAB中安装YALMIP及CPLEX详细步骤

热门文章

  1. Sublime Text 2.0.2 注册码
  2. 2021-06-27函数定义与参数
  3. c++ array容器 传参_C/C++常用技巧及初学者易错点汇总学习
  4. word 文字超出表格边框怎么办
  5. 【Django 2021年最新版教程30】ubuntu中停止和重启django项目
  6. 【Django 2021年最新版教程28】前端模板中 时间日期星期格式化
  7. ubuntu docker-compose: command not found
  8. Ubuntu如何修改用户密码
  9. python多进程与多线程_第十五章 Python多进程与多线程
  10. php 代码的分离和调用及注意事项(版本、变量及cookie与session的区别,PHP包含文件函数include、include_once、require、require_once区别和总结)