D Secret Passwords(思维+并查集)

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;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108655245