D. Secret Passwords(并查集)

传送门呢哥们到达时间哦i附件

(其实题目的意思很明显要用并查集)

(但是怎么并呢?当两个单词中有同一个字母就可以并起来)

(但是如果枚举单词的话复杂度是O(n^2)以上)

(那么其实要并的只有26个小写字母)

(因为出现在同一个单词的字母就是一个集合,直接合并)

(如果不很清晰,就这么想吧。)

(一开始什么都没有,然后把第一个单词abc合并,于是我们的集合是a,b,c)

(然后第二个单词是ade,因为我们有a所以可以获取d,e)

(这难道不是并查集的传递性吗?)

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+9;
int n,vis[maxn],pre[maxn],ans;
string a[maxn];
int find(int x){
	return x==pre[x]?pre[x]:pre[x]=find(pre[x]);
}
void join(int q,int w){
	pre[find(q)]=find(w);
}
int main()
{
	cin>>n;
	for(int i=0;i<=30;i++)	pre[i]=i;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		int b[27]={0};
		for(int l=a[i].length(),j=0;j<l;j++)
		{
			int s=a[i][j]-'a'+1;
			b[s]++;vis[s]++;
		}
		for(int q=1;q<=26;q++)
		{
			if(b[q]==0)	continue;
			for(int j=q+1;j<=26;j++)
			{
				if(b[j]==0)	continue;
				join(q,j);
			}
			break;
		}
	}
	for(int i=1;i<=26;i++)
	if(vis[i]&&find(i)==i)	ans++;
	cout<<ans;
}
原文地址:https://www.cnblogs.com/iss-ue/p/12895686.html