Codeforces Round #603 (Div. 2) D. Secret Passwords 并查集

链接:https://codeforces.com/contest/1263/problem/D

题意:给你n个字符串,如果其中两个字符串的某个元素相同,则被视为相同,问最后知道几个字符串就可以知道所有的字符串;

假设a字符串和c字符串等价,b和c字符串等价,那么a和b也等价。

并查集裸题;

count()返回集合中某个值元素的个数

code;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int fa[maxn];
string s[maxn];
set<int> vis;
int n;
int Find(int x)
{
    return x==fa[x]?x:fa[x]=Find(fa[x]);
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
     {
        cin>>s[i];
     }
    for(int i=1; i<=n+26; i++)
     fa[i]=i;
    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<s[i].size(); j++)
         fa[Find(i)]=fa[Find(n+s[i][j]-'a'+1)];
    }
    int ans=0;
    for(int i=1; i<=n; i++)
    {
        if(!vis.count(Find(i)))
        {
            ans++;
            vis.insert(Find(i));
        }
    }
    printf("%d
",ans);
    //system("pause");
    return 0;
}

另:合并每个串,然后压入set,最后输出set的大小即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int fa[maxn];
set<int> vis;
int n;
vector<string> v;
int Find(int x)
{
    return x==fa[x]?x:fa[x]=Find(fa[x]);
}
void Union(int x,int y)
{
    int fx=Find(x),fy=Find(y);
    if(fx!=fy)
     fa[fy]=fx;
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n+26; i++)
       fa[i]=i;
    for(int i=1; i<=n; i++)
    {
        string s;
        cin>>s;
        v.push_back(s);
        int t=s[0]-'a'+1;
        for(int j=1; j<s.size(); j++)
          Union(t,s[j]-'a'+1);
    }
    for(int i=0; i<v.size(); i++)
    {
        for(int j=0; j<v[i].size(); j++)
         vis.insert(Find(v[i][j]-'a'+1));//扫一遍字符串,找最终有几个爸爸
    }
    printf("%d
",vis.size());
    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/sweetlittlebaby/p/12762622.html