https://www.luogu.com.cn/problem/CF1263D
题意翻译
给定nn个字符串
- 如果存在一个或多个字母同时在字符串aa和bb中出现 这aa和bb就被分在同一组
- 如果aa和cc在同一组 bb和cc在同一组 则aa和bb也在同一组
问所有的字符串最后被分成几组
输入输出样例
输入 #1复制
4 a b ab d
输出 #1复制
2
输入 #2复制
3 ab bc abc
输出 #2复制
1
输入 #3复制
1 codeforces
输出 #3复制
1
说明/提示
In the second example hacker need to use any of the passwords to access the system.
思路:比较容易想到并查集。开始想的时候没想到怎么把同个颜色的尽可能连起来。发现以颜色为分类,看有多少个串有这个颜色,就把这些串全部union。这样就能达到有同色的全连,已经互连的也连了。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
LL fa[maxn];
string str[maxn];
vector<LL>a[110];
LL find(LL x)
{
if(x==fa[x]) return fa[x];
return fa[x]=find(fa[x]);
}
int main(void)
{
LL n;cin>>n;
for(LL i=1;i<=n;i++) fa[i]=i;
for(LL i=1;i<=n;i++)
{
cin>>str[i];
for(LL j=0;j<str[i].size();j++)
{
a[str[i][j]-'a'].push_back(i);
}
}
for(LL i=0;i<26;i++)
{
for(LL j=0;j<a[i].size();j++)
{
LL l=find(a[i][0]);
LL r=find(a[i][j]);
if(l!=r) fa[l]=r;
}
}
LL ans=0;
for(LL i=1;i<=n;i++)
{
if(fa[i]==i) ans++;
}
cout<<ans<<endl;
return 0;
}