并查集初步
题目:HDU 1213
题意就是有一群人要去吃饭,但是不认识的不能坐在一起,这就要我们将认识的人合并……
赤裸裸的并查集。但是开始有个天真的想法:
用一个set数组记录,每次将有关系的人的值变为前一个人的值。
然后仔细想一想明显是不行的……
比如这个数据:1 - 2 , 3 - 4 , 2 - 3
对于4个人的这个数据显然只需要一张桌子!因为都认识。。。。可是如果用上面的方法将会得到错误的答案!
所以只能用并查集了~~
不说了,贴代码+注释:
#include <cstdio> #include <algorithm> int set[1050]; int find(int x) { int t = x; while (t != set[t]) t = set[t]; return t; } void Union(int x , int y) { int a = find(x); int b = find(y); set[a] = b; } int main() { int T , n , m , a , b; int i , ans; scanf("%d" , &T); while (T --) { scanf("%d%d" , &n , &m); for (i = 1 ; i <= n ; i ++) set[i] = i; ans = 0; for (i = 0 ; i < m ; i ++) { scanf("%d%d" , &a , &b); if (find(a) != find(b)) // 看看是否属于同一个集合 { ans ++; // 若不是则ans + 1 Union(a , b); // 合并起来 } } printf("%d\n" , n - ans); } }
对于数据:
1
4 3
1 2
3 4
2 3
得到的树是这个样子的: