题目描述
小蓝正在和朋友们团建,有一个游戏项目需要两人合作,两个人分别拿到一棵大小为 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;
}