題目:
Time Limit: 1000MS | Memory Limit: 20000K | |
Total Submissions: 22216 | Accepted: 10804 |
Description
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.
Input
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
Output
Sample Input
100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 200 2 1 5 5 1 2 3 4 5 1 0 0 0
Sample Output
4 1 1傳送門:點擊打開鏈接
解題思路:
並查集的簡單應用。檢查有多少個元素和元素0在同一個集合之中。我們可以在進行並操作時,將小的點設爲父親節點,這樣的話,所有與0在一個集合中的元素的根節點都爲0,我們找出有多少個點的根節點爲你0即可。
代碼:
#include <cstdio>
#include <cstring>
const int MAXN = 3e4 + 10;
int set[MAXN];
int find(int p)
{
if(set[p] < 0) return p;
return set[p] = find(set[p]);
}
void join(int p, int q)
{
p = find(p), q = find(q);
if(p < q) set[q] = p;
if(p > q) set[p] = q;
}
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
if(0==n && 0==m) break;
memset(set, -1, sizeof(set));
while(m--)
{
int num, a;;
scanf("%d", &num);
scanf("%d", &a); num--;
while(num--)
{
int b;
scanf("%d", &b);
join(a, b);
}
}
int cnt = 1;
for(int i = 1; i < n; ++i)
{
if(0 == find(i)) cnt++;
}
printf("%d\n", cnt);
}
return 0;
}