codeforces div2 603 D. Secret Passwords
题目大意:
有很多的字符串,如果两个字符串有相同字母,就属于同一组,字符串a与b一组,b与c一组,那么a也与c一组,问这所有字符串可以被分成几组。
思路
我们只需要维护26个小写字母的并查集就可以了。同属于一个字符串里面的所有字母,肯定属于同一个集合中,因为其他任何字符和这个字符串的一个字符相同,那么就和这个字符串所有字符都建立了关系。所以我们只需要把每个字符串相邻两个字符加进一组,最后看26个字母被分成了几组。注意还要定义一个vis[]数组,因为有些字母可能并没有出现。
代码
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define debug freopen("in.txt","r",stdin),freopen("out.txt","w",stdout); using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 1e6+10; using namespace std; int N; int fa[300]; bool vis[300]; void init(){ for(char c = 'a';c<='z';c++) fa[c] = c; } int find(int x){ return (fa[x] == x)? x: fa[x] = find(fa[x]); } void join(int x,int y){ fa[find(x)] = find(y); } int main(){ ios; init(); cin>>N; while(N--){ string s;cin>>s; for(int i = 1;i<s.length();i++){ join(s[i-1],s[i]); } for(auto c:s) vis[c] = 1; } int cnt = 0; for(int i = 'a';i<='z';i++){ if(vis[i] && find(i) == i) cnt++; } cout<<cnt<<endl; return 0; }