蓝桥杯2024年第十五届省赛真题-团建

题目描述

小蓝正在和朋友们团建,有一个游戏项目需要两人合作,两个人分别拿到一棵大小为 n 和 m 的树,树上的每个结点上有一个正整数权值。

两个人需要从各自树的根结点 1 出发走向某个叶结点,从根到这个叶结点的路径上经过的所有结点上的权值构成了一个正整数序列,两人的序列的最长公共前缀即为他们的得分。给出两棵树,请计算两个人最多的得分是多少。

输入格式

输入的第一行包含两个正整数 n, m ,用一个空格分隔。

第二行包含 n 个正整数 c1, c2, · · · , cn ,相邻整数之间使用一个空格分隔,其中 ci 表示第一棵树结点 i 上的权值。

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

接下来 m − 1 行,每行包含两个正整数 pi, qi 表示第二棵树中包含一条 pi和 qi 之间的边。

输出格式

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

样例输入

2 2
10 20
10 30
1 2
2 1

样例输出

1

我比赛里用的是两层bfs+map。但是有问题,在c语言网上70分。

代码如下:

#include<iostream>
#include<cstring>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
#define fp(i,a,b) for(int i=a;i<=b;i++)
#define PII pair<int,int>
typedef  long long ll;
typedef double db;
const int N=1e6+10;
const int M=1e2+10;
const int mod=1e9+7;
int n,m;
int c[N],d[N];
vector<int>G[N];
vector<int>T[N]; 
map<PII,int>mp;
bool vis1[N],vis2[N];
int mmax=0;
struct node
{
	int x;
	int d;
};
void bfs1()
{
	queue<node>q;
	q.push({1,1});
	while(!q.empty())
	{
		node now=q.front();
		int x=now.x;
		int d=now.d;
		vis1[x]=1;
		q.pop();
		for(int i=0;i<G[x].size();i++)
		{
			int to=G[x][i];
			if(vis1[to])continue;
			mp[{c[x],c[to]}]=d;
			q.push({to,d+1});
		}
	}
}
void bfs2()
{
	queue<node>q;
	q.push({1,1});
	while(!q.empty())
	{
		node now=q.front();
		int x=now.x;
		int dd=now.d;
		vis2[x]=1;
		q.pop();
		for(int i=0;i<G[x].size();i++)
		{
			int to=G[x][i];
			if(vis2[to])continue;
			if(mp[{d[x],d[to]}]==dd)q.push({to,dd+1}),mmax=max(mmax,dd+1);
		}
	}
}
void solve()
{    
	cin>>n>>m;
	
	fp(i,1,n)cin>>c[i];
	fp(i,1,m)cin>>d[i];
	
	fp(i,1,n-1)
	{
		int u,v;
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	
	fp(i,1,m-1)
	{
		int p,q;
		cin>>p>>q;
		T[p].push_back(q);
		T[q].push_back(p);
	}
	
	bfs1();
	if(c[1]==d[1])mmax=1;
	bfs2();
	cout<<mmax<<"\n";
}
int main()
{
    int T;
//    cin>>T;
    T=1;
    while(T--){
        solve();
    }
    


    return 0;
}

如果只记录深度与上下的关系,确实存在一些冲突情况。

正解如下:

#include<iostream>
#include<cstring>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
#define fp(i,a,b) for(int i=a;i<=b;i++)
#define PII pair<int,int>
typedef  long long ll;
typedef double db;
const int N=1e6+10;
const int M=1e2+10;
const int mod=1e9+7;
int n,m;
int c[N],d[N];
vector<int>G[N];
vector<int>T[N]; 
bool vis1[N],vis2[N];
int mmax=0;
void dfs(int fn,int pn,int fm,int pm,int dep) {
	mmax=max(mmax,dep);
	map<int,int> mp;
	for (auto sonv:G[fn]) {
		if (sonv!=pn)mp[c[sonv]]=sonv;
	}
	for (auto sonm:T[fm]) {
		if (sonm!=pm) {
			if (mp.count(d[sonm])) {
				dfs(mp[d[sonm]],fn,sonm,fm,dep+1);
			}
		}
	}
}
void solve()
{    
	cin>>n>>m;
	
	fp(i,1,n)cin>>c[i];
	fp(i,1,m)cin>>d[i];
	
	fp(i,1,n-1)
	{
		int u,v;
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	
	fp(i,1,m-1)
	{
		int p,q;
		cin>>p>>q;
		T[p].push_back(q);
		T[q].push_back(p);
	}
	
	if(c[1]!=d[1])
	{
		cout<<0<<"\n";
		return;
	}
	
	dfs(1,0,1,0,1);
	cout<<mmax<<"\n";

}
int main()
{
    int T;
//    cin>>T;
    T=1;
    while(T--){
        solve();
    }
    
 
 
    return 0;
}

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值