团建
题目



思路:
-
搜索
-
数据规模->BFS
-
想“两棵树同时扩展”
-
核心:二元组(u,v)表示
树1:root->u 与 树2:root->v,经过的权值序列完全相同
(满足:u和v在同一层,c[u]=d[v])
-
从当前状态(u,v)扩展到下一个状态:
寻找:u的子结点权值 = v的子结点权值
如果有,deep++
-
需要保存(parent-u,parent-v),确保父->子,避免子->父
-
强调:
这题似乎并不合适用标记访问数组
不可随意将无向图改为有向图,会截断原来的通路
图解:

代码:
vector<int> e1[N];
vector<int> e2[N];
struct node{int u,v,pu,pv,stp;};//(u,v) (parent-u,parent-v)
int n,m,c[N],d[N],u0,v0,dep;//deep
void bfs()
{
queue<node> q;
node head;
int ui,vi,stpi;
if(c[1]==d[1]){
q.push({1,1,0,0,1});
dep++;
}
while(!q.empty()){
map<int,int> mp;//map<下标的权值,下标 >
head=q.front(); q.pop();
ui=head.u; vi=head.v; stpi=head.stp;
for(auto x:e1[ui]){
if(head.pu==x) continue;
mp[c[x]]=x;
}
for(auto y:e2[vi]){
if(head.pv==y) continue;
auto it=mp.find(d[y]);
if(it!=mp.end()){
q.push({it->second,y,ui,vi,stpi+1});
if(dep==stpi){//stpi->stpi+1 深度还停留在stpi 则深度++
dep++;
}
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>c[i];
}
for(int i=1;i<=m;++i){
cin>>d[i];
}
for(int i=1;i<=n-1;++i){
cin>>u0>>v0;
e1[u0].push_back(v0);
e1[v0].push_back(u0);
}
for(int i=1;i<=m-1;++i){
cin>>u0>>v0;
e2[u0].push_back(v0);
e2[v0].push_back(u0);
}
bfs();
cout<<dep;
return 0;
}

浙公网安备 33010602011771号