CF1263D Secret Passwords

发布时间 2023-08-23 14:44:33作者: One_JuRuo

思路

题目告诉我们有相同字母的密码就是等效的,等效性可以传递,所以我们可以考虑把所有等效的密码放在一起。

自然而然地想到了并查集,统计每个出现过某个字母的密码,然后一个字母一个字母的去合并等效密码。

接下来思考如何统计答案,如果合并完了再去统计,自然就很麻烦,但是我们可以边合并边统计,发现如果有两个等效密码合并,则会减少一个答案,所以可以在合并时统计。

AC code

#include<bits/stdc++.h>
using namespace std;
int n,fa[200005],ans;
char ch[55];
bool vis[26];
vector<int>v[26];
int find(int x){return (fa[x]==x)?x:fa[x]=find(fa[x]);}
int main()
{
	scanf("%d",&n),ans=n;
	for(int i=1;i<=n;++i) fa[i]=i;
	for(int i=1;i<=n;++i)
	{
		scanf("%s",ch),memset(vis,0,sizeof(vis));
		int m=strlen(ch);
		for(int j=0;j<m;++j)
		{
			if(vis[ch[j]-'a']) continue;//避免重复统计
			vis[ch[j]-'a']=1,v[ch[j]-'a'].push_back(i);
		}
	}
	for(int i=0;i<26;++i)
		if(v[i].size()>1)
			for(int j=1;j<v[i].size();++j)
				if(find(v[i][0])!=find(v[i][j])) fa[find(v[i][j])]=find(v[i][0]),ans--;
	printf("%d",ans);
	return 0;
}