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] 2dep2[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;
}
posted @ 2021-09-14 21:14  lahlah  阅读(44)  评论(0编辑  收藏  举报