擒贼先擒王(并查集)

擒贼先擒王(并查集)

题面

快过年了,犯罪分子也开始为年终奖奋斗了。晓哼的家乡出现了多次抢劫事件。由于强盗人数过于庞大,作案频繁,警方想查清楚到底有几个犯罪团伙实在太不容易了,不过警察叔叔还是搜集到了一些线索,需要咱们帮忙分析一下:
现在有10个强盗。
1号强盗与2号强盗是同伙。
3号强盗与4号强盗是同伙。
5号强盗与2号强盗是同伙。
4号强盗与6号强盗是同伙。
2号强盗与6号强盗是同伙。
8号强盗与7号强盗是同伙。
9号强盗与7号强盗是同伙。
1号强盗与6号强盗是同伙。
2号强盗与4号强盗是同伙。
有一点需要注意,强盗同伙的同伙也是同伙。你能帮助警方查出有多少个独立的犯罪团伙吗?

输入
第一行n m,n(n< 3000 )表示强盗的人数,m表示警方搜集到的m(m< 5000 )条线索。

接下来的m行每一行有两个数 a b。表示强盗a和强盗b是同伙。

输出
有多少个独立的犯罪团伙

样例
样例输入1

10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4

样例输出1

3

题目概括

我们要找出所有数据,依照题目关系条件,可以组成的树的棵数

思路

并查集不清楚的朋友看这儿
先按照输入建树,再统计有多少个结点的上级是它本身(根节点)
最后把它A掉

AC代码和注释

#include<bits/stdc++.h>
using namespace std;
int n,m;
int parent[5005];
void init(int n) {//初始化 
    for(int i = 1;i <= n;i ++) {
        parent[i] = i;
    }
}
int find(int t){//查找 
	if(parent[t] == t) return t;
	else return parent[t] = find(parent[t]);
}
void merge(int r1,int r2){//合并 
	parent[find(r2)] = find(r1);
}
int main(){
	cin >> n >> m;
	init(n);
	for(int i = 1;i <= m;i ++){
		int x,y;
		cin >> x >> y;
		merge(x,y);
	}
	int ans = 0;
	for(int i = 1;i <= n;i ++){//记录有多少个结点的上级是它本身(根节点)
		if(parent[i] == i) ans ++;
	}
	cout << ans;
	return 0;
}

小编蒟蒻一个,有什么问题请大佬不惜赐教Orz

posted @ 2023-07-23 15:29  骆美辰  阅读(23)  评论(0编辑  收藏  举报
lock: { enable: true, background: 'https://img1.baidu.com/it/u=2788089125,168843488&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1690563600&t=35fa4326e773b3fbf83562ad746b7cd2',//锁屏背景 strings: [ 'Every win named never give up 每一份胜利都叫不放弃',//签名 ], },