AT2063 [AGC005E] Sugigma: The Showdown
https://www.luogu.com.cn/problem/AT2063
首先对两个点为根分别对两棵树dfs一边求出其他点深度
显然如果
d
e
p
1
[
u
]
>
=
d
e
p
2
[
u
]
dep1[u]>=dep2[u]
dep1[u]>=dep2[u]那么
u
u
u点是到不了的
考虑那种情况是-1
容易发现如果在第一棵树上的一条边 x − > y x->y x−>y在第二棵树上的距离 > 2 >2 >2那么就是-1
否则找第一棵树上能到达的点,且在第二棵树上最深的结点编号
跑过去然后等死就行了
答案就是 2 ∗ d e p 2 [ x ] 2*dep2[x] 2∗dep2[x]
code:
#include<bits/stdc++.h>
#define N 200050
using namespace std;
int n, m, fa[N], dep[N], ans;
vector<int> g[N], gg[N];
void dfs(int u) {
for(int i = 0; i < gg[u].size(); i ++) {
int v = gg[u][i];
if(v == fa[u]) continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dfs(v);
}
}
int check(int u, int v) { //printf(" %d %d\n", u, v);
if(dep[u] < dep[v]) swap(u, v);
if(dep[u] == dep[v]) return fa[u] == fa[v];
if(dep[u] == dep[v] + 1) return fa[u] == v;
if(dep[u] == dep[v] + 2) return fa[fa[u]] == v;
return 0;
}
void dfss(int u, int fa, int d) {
if(d >= dep[u]) return ;
ans = max(ans, dep[u]);
for(int i = 0; i < g[u].size(); i ++) {
int v = g[u][i];
if(v == fa) continue;
if(!check(u, v)) puts("-1"), exit(0);
dfss(v, u, d + 1);
}
}
int s, t;
int main() {
scanf("%d%d%d", &n, &s, &t);
for(int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v), g[v].push_back(u);
}
for(int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v);
gg[u].push_back(v), gg[v].push_back(u);
}
dfs(t);
// for(int i = 1; i <= n; i ++) printf("%d ", fa[i]);
dfss(s, s, 0);
printf("%d", ans * 2);
return 0;
}