[AGC005E] Sugigma: The Showdown
先考虑什么时候输出 。
我们令 表示树 中从 点走到 经过的边数,同理 表示树 中从 点到 经过边数。
我们对于一个点 ,当且仅当 时, 点才可以到达 。如果 ,那么一定会被抓到。
如果存在两个点 ,满足 和 直接相连,且 点可以到达 且可以到达 的时候,如果 两点在树 的距离 时,那么应该输出 ,应为这时候 B 一定抓不到 A。
反之,如果不存在这样的点对 ,那么 最大的 使得 可以到达 就是答案,即 走到 ,然后一直不走等着被抓。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
const int N = 2e5 + 5;
vector<int> G1[N], G2[N];
int n, a, b, dis[N];
int ans, f[N];
void dfs(int u, int fa)
{
dis[u] = dis[fa] + 1;
f[u] = fa;
for (int j : G2[u])
{
if (j != fa) dfs(j, u);
}
}
void dfs2(int u, int fa, int len)
{
if (len >= dis[u])
{
return;
}
ans = max(ans, dis[u]);
//printf("%d %d\n", u, dis[u]);
for (int j : G1[u])
{
if (j != fa)
{
int nlen = len + 1;
int nu = u, nv = j;
if (f[nu] != nv && f[nv] != nu && f[f[nu]] != nv && f[f[nv]] != nu && f[nu] != f[nv])
{
printf("-1\n");
exit(0);
}
dfs2(j, u, nlen);
}
}
}
int main()
{
scanf("%d%d%d", &n, &a, &b);
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G1[u].emplace_back(v);
G1[v].emplace_back(u);
}
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G2[u].emplace_back(v);
G2[v].emplace_back(u);
}
dis[b] = -1;
dfs(b, b);
dfs2(a, 0, 0);
printf("%d\n", ans * 2);
return 0;
}

浙公网安备 33010602011771号