Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers.
One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.
For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.
Input
The input starts with an integer T(1<=T<=25) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N,M<=1000). N indicates the number of friends, the friends are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other. There will be a blank line between two cases.
Output
For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.
Sample Input
2
5 3
1 2
2 3
4 5
5 1
2 5
Sample Output
2
4
问题简述:一个人办晚会,来参加的人相互是朋友的可以坐一起,间接朋友也可以坐一起。问要几张桌子。
问题思路:用并查集寻找父节点,有相同父节点的坐一张桌子。
#include<iostream>
#define maxn 10001
int parentroot[maxn];
int findroot(int s) {
if (s != parentroot[s]) {
parentroot[s] = findroot(parentroot[s]);//压缩路径,否则会超时
}
return parentroot[s];
}
int main() {
int t, n, m;//要在循环外定义,否则会WA
int a, b;
std::cin >> t;
while (t--) {
std::cin >> n >> m;
for (int i = 0; i < maxn; i++) {
parentroot[i] = i;
}
while (m--) {
std::cin >> a >> b;
int x = findroot(a);
int y = findroot(b);
if (x != y) {
parentroot[x] = y;
}
}
int account = 0;
for (int i = 1; i <= n; i++) {
if (parentroot[i] == i) {
account++;
}
}
std::cout << account << std::endl;
}
return 0;
}