AtCoder AGC005E Sugigma: The Showdown (博弈论)
题目链接
https://atcoder.jp/contests/agc005/tasks/agc005_e
题解
完了真的啥都不会了……
首先,显然如果某条A树的边对应B树上的距离大于等于\(3\), 且A能走到该边的某个端点,那么答案就是\(-1\).
A能走到某个点当且仅当从A的起点到这个点的路径上每个点与A起点的距离都小于与B起点的距离。
然后直接在A树上从根开始DFS,如果走不到了就返回,否则用与\(y\)的距离更新答案;同时在遍历每条边的时候判断是否可以\(-1\).
时间复杂度\(O(n\log n)\), 但是由于距离不超过\(3\)的特殊性可以优化成\(O(n)\).
上面的性质我都发现了,可是我做不出来这题……到底是什么情况……
代码
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cassert>
using namespace std;
const int N = 2e5;
const int lgN = 18;
const int INF = 1e7;
struct Edge
{
int v,nxt;
} e1[(N<<1)+3],e2[(N<<1)+3];
int fe1[N+3],fe2[N+3];
int dep1[N+3],dep2[N+3];
int fa2[N+3][lgN+3];
int n,en1,en2,s1,s2,ans;
void addedge1(int u,int v)
{
en1++; e1[en1].v = v;
e1[en1].nxt = fe1[u]; fe1[u] = en1;
}
void addedge2(int u,int v)
{
en2++; e2[en2].v = v;
e2[en2].nxt = fe2[u]; fe2[u] = en2;
}
void dfs1(int u,int prv)
{
for(int i=fe1[u]; i; i=e1[i].nxt)
{
int v = e1[i].v;
if(v==prv) continue;
dep1[v] = dep1[u]+1;
dfs1(v,u);
}
}
void dfs2(int u)
{
for(int i=1; i<=lgN; i++) fa2[u][i] = fa2[fa2[u][i-1]][i-1];
for(int i=fe2[u]; i; i=e2[i].nxt)
{
int v = e2[i].v;
if(v==fa2[u][0]) continue;
fa2[v][0] = u; dep2[v] = dep2[u]+1;
dfs2(v);
}
}
int LCA(int u,int v)
{
if(dep2[u]<dep2[v]) swap(u,v);
int dif = dep2[u]-dep2[v];
for(int i=0; i<=lgN; i++)
{
if(dif&(1<<i)) {u = fa2[u][i];}
}
if(u==v) return u;
for(int i=lgN; i>=0; i--)
{
if(fa2[u][i]!=fa2[v][i]) {u = fa2[u][i],v = fa2[v][i];}
}
return fa2[u][0];
}
void dfs(int u,int fa)
{
if(dep1[u]>=dep2[u]) {return;}
ans = max(ans,dep2[u]);
for(int i=fe1[u]; i; i=e1[i].nxt)
{
int v = e1[i].v;
if(v==fa) continue;
if(dep2[u]+dep2[v]-2*dep2[LCA(u,v)]>2) {ans = INF; return;}
dfs(v,u);
}
}
int main()
{
scanf("%d%d%d",&n,&s1,&s2);
for(int i=1; i<n; i++)
{
int u,v; scanf("%d%d",&u,&v);
addedge1(u,v); addedge1(v,u);
}
for(int i=1; i<n; i++)
{
int u,v; scanf("%d%d",&u,&v);
addedge2(u,v); addedge2(v,u);
}
dfs1(s1,0); dfs2(s2);
ans = 0; dfs(s1,0);
printf("%d\n",ans==INF?-1:ans*2);
return 0;
}
AtCoder AGC005E Sugigma: The Showdown (博弈论)的更多相关文章
- Atcoder Grand Contest 005 E - Sugigma: The Showdown(思维题)
洛谷题面传送门 & Atcoder 题面传送门 记先手移动棋子的树为红树,后手移动棋子的树为蓝树. 首先考虑一个性质,就是如果与当前红色棋子所在的点相连的边中存在一条边,满足这条边的两个端点在 ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- AtCoder Grand Contest 005
AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...
- AtCoder Grand Contest
一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...
- Atcoder/Topcoder 口胡记录
Atcoder/Topcoder 理论 AC Atcoder的❌游戏示范 兴致勃勃地打开一场 AGC 看 A 题,先 WA 一发,然后花了一年时间 Fix. 看 B 题,啥玩意?这能求? 睡觉觉. e ...
- 【AtCoder】AGC005
AGC005 A - STring 用一个栈,如果遇到S就弹入,如果遇到T栈里有S就弹出栈顶,否则T在最后的串里,最后计算出的T和栈里剩的S就是答案 #include <bits/stdc++. ...
- RE:从零开始的AGC被虐(到)生活(不能自理)
RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...
- A@G!C005
AGC005 A STring 不会,有没有老鸽蕉蕉我/kk/kel/dk https://agc005.contest.atcoder.jp/submissions/7926986 B Minimu ...
- AtCoder AGC002E Candy Piles (博弈论)
神仙题..表示自己智商不够想不到... 好几次读成最后拿的赢了,导致一直没看懂题解... 题目链接: https://atcoder.jp/contests/agc002/tasks/agc002_e ...
随机推荐
- Scala学习七——包和引入
一.本章要点 包也可也可以像内部类那样嵌套 包路径不是绝对路径 包声明链x.y.z并不自动将中间包x和x.y变成可见 位于文件顶部不带花括号的包声明在整个文件范围内有效 包对象可以持有函数和变量 引入 ...
- winform messageBox.Show()
MessageBox.Show(" 5 个参数...... ", " 亮仔提示", MessageBoxButtons.OKCancel, ...
- Stacey矩阵简介
1. Stacey 矩阵包含哪几个区域? 1区:Simple 第一个区域,需求明确,技术(解决方案)也确定,这类项目就是简单的项目(Simple):比如注册一个新公司,需求很明确,手续也很清楚,就那么 ...
- 客户端相关知识学习(八)之Android“.9.png”
参考 Android中.9图片的含义及制作教程 .9.png Android .9.png 的介绍
- ZROIDay4-比赛解题报告
ZROIDay4-比赛解题报告 扯闲话 感觉这个出题人的题做起来全都没感觉啊,今天又凉了,T1完全不知道什么意思,T2只会暴力,T3现在还不懂什么意思,真的太菜了 A 题意半天没搞懂爆零GG了,讲了一 ...
- Laravel 表单验证创建“表单请求”实现自定义请求类
按照文档创建表单请求自定义类以后,调用总是403页面,咨询大佬说: public function authorize() { // 在表单验证类的这个方法这里要返回true,默认返回false,这个 ...
- java字符串大小写转换
String test="SHA34cccddee"; System.out.println(test.toUpperCase());//小写转大写 String test= ...
- 嵌套For循环性能优化
请对以下的代码进行优化 for (int i = 0; i < 1000; i++) for (int j = 0; j < 100; j++) for (int k = 0; k < ...
- java基础4(线程)
1.请简单描述什么是并行,什么是并发? 并行:指两个或多个事件在同一时刻发生(同时发生). 并发:指两个或多个事件在同一个时间段内发生. 通俗易懂版: 你吃饭吃到一半,电话来了,你一直到吃完了以后才去 ...
- Linux系统介绍及部署
Linux系统介绍及部署1.常见操作系统 windows.Linux(类unix系统).Android.iOS.unix(HP UNIX)2.操作系统构成 外壳(shell)+驱动+内核3.常见Lin ...