链接:https://vjudge.net/problem/POJ-1611#author=SCU2018
题意:
警察抓贩毒集团。有不同类型的犯罪集团,人员可能重复,集团内的人会相互接触。现在警察在其中一人(0号)身上搜出毒品,认为与这个人直接接触或通过其他人有间接接触的人都是嫌疑犯。问包括0号犯人共有多少嫌疑犯?
思路:
并查集模板,在组内进行操作,先将每组第一个设为队首,当找父亲找到的为0时,
优先将0作为父亲,这样与0有间接和直接接触的人父亲都为0,
最后遍历一遍每个点的父亲就好。
代码:
#include <iostream>
#include <memory.h>
#include <string>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
using namespace std;
const int MAXN = 30000+10;
int n,m;
int Father[MAXN];
int a[MAXN];
int Get_F(int x)
{
return Father[x] = Father[x] == x ? x:Get_F(Father[x]);
}
int main()
{
while (cin >> n >> m && n)
{
for (int i = 0;i<n;i++)
Father[i] = i;
int num;
for (int i = 1;i<=m;i++)
{
cin >> num;
for (int j = 0;j < num;j++)
cin >> a[j];
//sort(a,a+num);
int f = Get_F(a[0]);
for (int j = 1;j < num;j++)
{
int now = Get_F(a[j]);
if (f != now && now != 0)
{
Father[now] = f;
}
else if (f != now && now == 0)
{
Father[f] = now;
}
}
}
int sum = 0;
for (int i = 0;i<n;i++)
if (Get_F(i) == 0)
sum++;
cout << sum << endl;
}
return 0;
}