大致由一个整数数组(pre[])和两个函数(join()/find())组成
int find(int x){
if(pre[x]==x) return x;
else{
pre[x]=find(x);
return pre[x];
}
}
int join(int x,int y){
int a,b;
a=find(x);
b=find(y);
if(a!=b) pre[a]=b;
}
例题有
7-8 朋友圈 (25 分)
#include<bits/stdc++.h>
using namespace std;
int stu[300010];
int ans[300010];
/*
并查集由一个整数型数组pre[x](记录x的前导点)和两个函数(find和join)组成
*/
int find(int x){
if(stu[x]==x){
return stu[x];
}else{
stu[x]=find(stu[x]); //例 123 14 join(1,2) join(1,3) join(1,4) 连成1234 朋友圈里有四个人
return stu[x];
}
}
int join(int x,int y){
int a,b;
a=find(x);
b=find(y);
if(a!=b){
stu[a]=b;
}
}
int main(){
int n,m; //n学生总数 m俱乐部个数
int x,y,z;
cin>>n>>m;
for(int i=1;i<=n;i++){ //初始化
stu[i]=i;
}
for(int i=0;i<m;i++){
cin>>z>>x; //俱乐部的人数和第一位学生
for(int j=1;j<z;j++){
cin>>y;
join(x,y);
}
}
int max=0; //朋友圈的最大人数
for(int i=1;i<=n;i++){
int c = find(i); //例 i从1到4 find函数最终找到的都是4 5到7find的结果都是7
ans[c]++; //所以ans[4]会加4次等于4 ans[7]等于3
if(max<ans[c]){
max=ans[c];
}
}
cout<<max;
/*
如果要找朋友圈的个数 判断 stu[i]==i 因为 stu[4]=4 stu[7]=7
int count=0;
for(int i=1;i<=n;i++){
if(stu[i]==i){
count++;
}
}
cout<<count;
*/
return 0;
}
7-17 社交集群 (30 分)
#include<bits/stdc++.h>
using namespace std;
//和朋友圈那题相似都使用并查集
int people[1001];
int find(int x){
if(people[x]==x){
return people[x];
}else{
people[x]=find(people[x]);
return people[x];
}
}
int join(int x,int y){
int a,b;
a=find(x);
b=find(y);
if(a!=b){
people[a]=b;
}
}
bool cmp(int x,int y){ //从大到小排序 非增序
return x>y;
}
int main(){
int n;
int h[1001]={0}; //先初始化 以便后面标记
int ans[1001]={0};
int res[1001]={0}; //存储每个兴趣圈里的人数
char c; //冒号
for(int i=1;i<=1001;i++){
people[i]=i;
}
cin>>n;
for(int i=1;i<=n;i++){ //修改从1开始 因为下面有标记
int x;
cin>>x>>c;
for(int j=1;j<=x;j++){
int y;
cin>>y;
if(h[y]==0){ //兴趣没被标记
h[y]=i;
}else{ //被标记过了就合并(就是一个兴趣圈超过了两个人)
join(h[y],i);
}
}
}
int max=0;
int count=0; //开始计算兴趣圈个数 和之前的朋友圈题目差不多
for(int i=1;i<=n;i++){ //(查找用户)计算兴趣圈个数
if(people[i]==i){
count++;
}
res[find(i)]++; //记录兴趣圈人数 假如1234有关联就会自加四次 而find()的值是不变的 我理解为find()指向这条关系的终点
}
sort(res,res+1001,cmp);
cout<<count<<endl;
int flag=0;
for(int i=0;i<1001;i++){
if(res[i]!=0){
cout<<res[i];
flag++;
}
if(flag!=count){
cout<<" ";
}
if(flag==count){
break;
}
}
return 0;
}