并查集特别好玩,已经不亦乐乎
并查集我一直没敢做,就是那个经典的犯罪团伙我下午试试,做完了,就花了半个多小时,学习和使用!
先上题
题目描述 Description
警察抓到了n个罪犯,警察根据经验知道他们属于不同的犯罪团伙,却不能判断有多少个团伙,但通过警察的审讯,知道其中的一些罪犯之间相互认识,已知同一犯罪团伙的成员之间直接或间接认识。有可能一个犯罪团伙只有一个人。请你根据已知罪犯之间的关系,确定犯罪团伙的数量。已知罪犯的编号从1至n。
输入描述 Input Description
第一行:n(<=10000,罪犯数量),
第二行:m(<100000,关系数量)
输出描述 Output Description
一个整数,犯罪团伙的数量。
样例输入 Sample Input
11
8
1 2
4 5
3 4
1 3
5 6
7 10
5 10
8 9
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
共10个测试数据:
(1)5个数据n<=1000,m<=5000;
(2)5个数据:10000>n〉=9000, 100000>m〉=90000;
之后便是我的代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 500000;
int uset[MAX],r[MAX];
void makeset(int size){
for(int i=0;i<size;i++) uset[i]=i;
}
int fine(int x){
if(x!=uset[x]) uset[x]=fine(uset[x]);
return uset[x];
}
void u(int x,int y){
if((x=fine(x))==(y=fine(y))) return;
if(r[x]>r[y]) uset[x]=y;
else{
uset[y]=x;
if(r[x]==r[y]) r[y]++;
}
}
int main(){
memset(r,0,sizeof(r));
int n,m,x,y,k=0;
cin>>n;
cin>>m;
makeset(n);
for(int i=0;i<m;i++){
cin>>x>>y;
u(x,y);
}
for(int i=0;i<=m;i++) if(uset[i]==i) k++;
cout<<k;
}
好了结题报告结束,没错我就是这么草率