【第十五届蓝桥杯】【C】【大学A组】【D题】【团建】【个人题解】


题目描述
小蓝正在和朋友们团建,有一个游戏项目需要两人合作,两个人分别拿到一棵大小为 n 和 m 的树,树上的每个结点上有一个正整数权值。  
两个人需要从各自树的根结点 1 出发走向某个叶结点,从根到这个叶结点的路径上经过的所有结点上的权值构成了一个正整数序列,两人的序列的最长公共前缀即为他们的得分。给出两棵树,请计算两个人最多的得分是多少。

输入格式
输入的第一行包含两个正整数 n, m,用一个空格分隔。  
第二行包含 n 个正整数 , ,··· , ,相邻整数之间使用一个空格分隔,其中  表示第一棵树结点 i 上的权值。  
第三行包含 m 个正整数 , ,···, ,相邻整数之间使用一个空格分隔,其中  表示第二棵树结点 i 上的权值。  
接下来 n - 1 行,每行包含两个正整数 ,  表示第一棵树中包含一条  和之间的边。  
接下来 m - 1 行,每行包含两个正整数 ,  表示第二棵树中包含一条 和  之间的边。

输出格式
输出一行包含一个整数表示答案。

输入输出样例
样例输入1    
2 2
10 20
10 30
1 2
2 1
样例输出1    1
样例输入2    
5 4
10 20 30 40 50
10 40 20 30
1 2
1 3
2 4
3 5
1 2
1 3
3 4
样例输出2    2
提示
对于 20% 的评测用例,1 ≤ n, m ≤ 500 ;  
对于所有评测用例,1 ≤ n, m ≤ 2 × ,1 ≤ ,  ≤ 10^8 ,1 ≤ ,  ≤ n ,1 ≤ ,  ≤ m,对于任意结点,其儿子结点的权重互不相同。

代码

​
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
using ll = long long;
ll N = 1e5 + 10;
ll M = 1e5 + 10;
ll ans = 0;
vector<pair<ll, vector<ll>>> pa(N + 1);
vector<pair<ll, vector<ll>>> pb(M + 1);
void dfs(ll na, ll fa, ll nb, ll fb, ll dep)
{
    map<ll, ll> mp;
    ans = max(ans, dep);
    for (int i = 0; i < pa[na].second.size(); i++)
    {
        if (pa[na].second[i] != fa)
        {
            mp[pa[pa[na].second[i]].first] = pa[na].second[i];
        }
    }
    for (int i = 0; i < pb[nb].second.size(); i++)
    {
        if (pb[nb].second[i] != fb)
        {
            if (mp.count(pb[pb[nb].second[i]].first))
            {
                dfs(mp[pb[pb[nb].second[i]].first], na, pb[nb].second[i], nb,dep + 1);
            }
        }
    }
}
int main()
{
      cin >> N >> M;
    for (int i = 1; i <= N; i++)
    {
        cin >> pa[i].first;
    }
    for (int i = 1; i <= M; i++)
    {
        cin >> pb[i].first;
    }
    for (int i = 1; i <= N - 1; i++)
    {
        ll a, b;
        cin >> a >> b;
        pa[a].second.push_back(b);
        pa[b].second.push_back(a);
    }
    for (int i = 1; i <= M - 1; i++)
    {
        ll a, b;
        cin >> a >> b;
        pb[a].second.push_back(b);
        pb[b].second.push_back(a);
    }
    if (pa[1].first != pb[1].first)
    {
        cout << 0 << endl;
        return 0;
    }

    dfs(1, 0, 1, 0, 1);
    cout << ans << endl;

}

​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值