核心思路:你一进某个点,就只会保留和它同类型的点,所以你最终能活动的范围,其实就是“同类型点构成的子图里,你所在连通块的大小”。
做法很直接:在原树上按类型分开跑连通块(0 和 1 各自连),算出每个点所属连通块大小,取最大值,把所有块大小等于最大值的点输出即可。
void solve(){
int n;cin>>n;
vi a(n+1);
for(int i=1;i<=n;++i){
cin>>a[i];
}
vvi g(n+1);
for(int i=1;i<=n-1;++i){
int u,v;cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
vi vis(n+1,0),sz(n+1,0);
for(int i=1;i<=n;++i){
if(vis[i]){
continue;
}
vi st,comp;
st.push_back(i);
vis[i]=1;
while(!st.empty()){
int u=st.back();
st.pop_back();
comp.push_back(u);
for(int j=0;j<(int)g[u].size();++j){
int v=g[u][j];
if(vis[v]||a[v]!=a[u]){
continue;
}
vis[v]=1;
st.push_back(v);
}
}
int cnt=(int)comp.size();
for(int j=0;j<cnt;++j){
sz[comp[j]]=cnt;
}
}
int mx=0;
for(int i=1;i<=n;++i){
if(sz[i]>mx){
mx=sz[i];
}
}
vi ans;
for(int i=1;i<=n;++i){
if(sz[i]==mx){
ans.push_back(i);
}
}
cout<<ans.size()<<endl;
for(int i=0;i<(int)ans.size();++i){
cout<<ans[i]<<" ";
}
cout<<endl;
}

京公网安备 11010502036488号