欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

白魔法师-----------------------思维(dfs+并查集)

程序员文章站 2022-03-13 17:05:23
...

白魔法师-----------------------思维(dfs+并查集)

白魔法师-----------------------思维(dfs+并查集)
解析:
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;
 }