题目链接:
题目描述:
有一天,一个哥们要过生日,寻思招待一顿,摇了很多朋友,但是朋友之间如果完全不认识(可以间接认识:AB认识,BC认识——>AC认识),坐在一起会尴尬,所以不会坐在一起,所以他不知道要用多少张桌子,想算一下(yy:他家卖桌子的,所以不会缺桌子,他家的桌子很大,可以坐很多很多人)
输入描述:
第一行表示输入数据组数
对于每组数据:
第一行两个数字n, m表示摇了n个哥们,m表示一共输入互相认识的对数
之后m行每行两个数,表示A与B互相认识。
输出描述:
每组数据输出一个整数,表示需要的桌子数
思路:
并查集,两个人相互认识,就合并,最后求桌子数,相当于求父亲是自己的结点个数,因为如过父亲节点是自己的话表示他铁定能占一张桌子,不管谁跟他一张桌子,或有没有人跟他一桌,他这张桌子占定了。很浅显的道理鄙人就不再赘述了。
烂代码如下:
/*************************************************************************
> File Name: hdu_1213.cpp
> Author: dulun
> Mail: dulun@xiyoulinux.org
> Created Time: 2016年03月28日 星期一 21时08分43秒
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define LL long long
using namespace std;
const int N = 50086;
int p[N];
int find(int x) { return p[x] == x? x: p[x] = find(p[x]); }
void init() { for(int i = 1; i < N; i++) p[i] = i; }
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, m;
int ans = 0;
scanf("%d%d", &n, &m);
init();
for(int i = 0; i < m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
a = find(a);
b = find(b);
if(a != b) p[a] = b;
}
for(int i = 1; i <= n; i++)
{//找父亲为自己的结点的个数
if(p[i] == i) ans++;
}
printf("%d\n", ans);
}
return 0;
}