白魔法师-----------------------思维(dfs+并查集)
程序员文章站
2022-03-13 17:05:23
...
解析:
dfs维护每一个连通块内部成员数量,取连通块数量最大的一个。然后枚举黑色节点。判断与黑色节点相连的点是不是属于白色连通块里,如果属于那么总的个数就是 size[find(x)]+1 和之前答案取最大值
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1000;
int e[N*2],ne[N*2],idx,h[N];
int n,u,v;
int fa[N];
int size[N];
int ans=0;
char s[N];
void add(int a,int b)
{
e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
int find(int x)
{
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
void dfs(int u,int father)
{
for(int i=h[u];~i;i=ne[i])
{
int v=e[i];
if(v==father) continue;
if(s[u]=='W'&&s[v]=='W')
{
int x=find(u),y=find(v);
if(x!=y)
{
fa[x]=y;
size[y]+=size[x];
size[x]=0;
ans=max(ans,size[y]);
}
}
dfs(v,u);
}
}
int main()
{
cin>>n>>(s+1);
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++)
{
fa[i]=i;
if(s[i]=='W') size[i]=1;
}
for(int i=1;i<=n-1;i++)
{
cin>>u>>v;
add(u,v);add(v,u);
}
dfs(1,-1);
for(int i=1;i<=n;i++)
{
if(s[i]=='W') continue;
int sum=0;
for(int j=h[i];~j;j=ne[j])
{
v=e[j];
if(s[v]=='W') sum+=size[find(v)];
}
ans=max(sum+1,ans);
}
cout<<ans<<endl;
}
上一篇: 使用RecyclerView实现两种不同Item布局
下一篇: RecyclerView三种布局