并查集的结题报告

并查集特别好玩,已经不亦乐乎

并查集我一直没敢做,就是那个经典的犯罪团伙我下午试试,做完了,就花了半个多小时,学习和使用!

先上题
题目描述 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;
}

好了结题报告结束,没错我就是这么草率

    原文作者:犯罪团伙问题
    原文地址: https://blog.csdn.net/a3995/article/details/52155411
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞