并查集
1.作用:将不连通的点分成不同的树,可以很快的查处这些点属于几块,不想交的集合中没有相同的元素。
2.并查集有2个核心操作:
查找:查找元素所在的集合(这里的集合并不是特指Set这种数据结构,是指广义的数据集合)。
合并:将两个元素所在的集合合并为一个集合。
P1551 亲戚
#include<bits/stdc++.h>
using namespace std;
int f[5010];
int find(int x){
if(x==f[x]) return x;
return find(f[x]);
}//寻找组长
int main(){
int n,m,p,x,y;
cin>>n>>m>>p;
for(int i=1;i<=n;i++)f[i]=i;//每一个数自成一个集合
for(int i=1;i<=m;i++){
cin>>x>>y;
int fx=find(x),fy=find(y);
if(fx!=fy){
f[fx]=fy;//进行合并操作
}
}
for(int i=1;i<=p;i++){
cin>>x>>y;
int fx=find(x),fy=find(y);
if(fx==fy)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}//进行判断
return 0;
}
哈希
主要是解决如何让每一个字符串及其子串都能获得其独特数字来表示,这里有一个比较常用的方法是通过乘以(131 或 13331 或者其他特殊的素数)来解决,乘以一个素数能有效减少不同字符串数字相等的冲突,如果这个素数还比较特殊,那么冲突的概率基本上就可以忽略不计了。
P3370 【模板】字符串哈希
#include<bits/stdc++.h>
using namespace std;
const int mod=1000;
vector<string> m[mod];
int ans,n;
void ha(string s){
int hs=0;
for(int i=0;i<s.size();i++){
hs=(hs*130+s[i])%mod;
}//进行进制转换
for(int i=0;i<m[hs].size();i++){
if(m[hs][i]==s)return;
}
m[hs].push_back(s);//进行元素压入
ans++;
}
int main(){
cin>>n;
string s;
for(int i=1;i<=n;i++){
cin>>s;
ha(s);
}//进行装元素
cout<<ans;
return 0;
}