[ AGC005 E ] Sugigma: The Showdown

题目

Atcoder

思路

001.png 002.png 003.png 004.png

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n, A, B, d[N], st[N], f[N];
int h1[N], h2[N], val[N << 2], ptr[N << 2], idx;
void add(int h[], int a, int b) { val[idx] = b, ptr[idx] = h[a], h[a] = idx++; }
void DFS_blue(int u, int fa) {
    for (int i = h2[u], v = val[i]; i != -1; i = ptr[i], v = val[i]) 
        if (v != fa) f[v] = u, d[v] = d[u] + 1, DFS_blue(v, u);
}
struct EDGE { int a, b; } E[N];
bool check(int a, int b) {
    if (d[a] < d[b]) swap(a, b);
    // 此时 a 在下, b 在上
    if (d[a] == d[b]) return f[a] == f[b];
    if (d[a] == d[b] + 1) return f[a] == b;
    if (d[a] == d[b] + 2) return f[f[a]] == b;
    // 此处判断可以画图理解
    return false;
}
int res;
// r 即红树上 u 到 A 起点的距离
void DFS_red(int u, int fa, int r) {
    if (d[u] <= r) return;
    if (st[u]) cout << -1 << endl, exit(0);
    res = max(res, d[u]);
    for (int i = h1[u], v = val[i]; i != -1; i = ptr[i], v = val[i])
        if (v != fa) DFS_red(v, u, r + 1);
}
int main() {
    cin >> n >> A >> B;
    memset(h1, -1, sizeof h1), memset(h2, -1, sizeof h2);
    for (int i = 1, a, b; i < n && cin >> a >> b; i++)
        add(h1, a, b), add(h1, b, a), E[i].a = a, E[i].b = b;
    for (int i = 1, a, b; i < n && cin >> a >> b; i++)
        add(h2, a, b), add(h2, b, a);
    DFS_blue(B, 0);
    for (int i = 1; i < n; i++) 
        if (!check(E[i].a, E[i].b)) 
            st[E[i].a] = st[E[i].b] = true; // 标记端点
    DFS_red(A, 0, 0);
    cout << res * 2 << endl;
    return 0;
}
posted @ 2021-05-20 18:04  Protein_lzl  阅读(36)  评论(0编辑  收藏  举报