GDUT-寒假专题训练3--The Suspects

题目:

2019冠状病毒病(英语:Coronavirus disease 2019,缩写:COVID-19 ),是一种由严重急性呼吸系统综合症冠状病毒2型(缩写:SARS-CoV-2)引发的传染病。此病在全球各国大规模爆发并急速扩散,成为人类历史上致死人数最多的流行病之一。 很显然,目前最好的办法就是将所有可能的患者都隔离起来。 现在某高校正在排查可能的患者,这个高校中有多个社团,每个社团经常进行内部交流,一名学生可能会加入多个社团。学校认为一旦某个社团里出现一名可疑患者,这整个社团的学生都被视为是可能的患者。 现在请你帮忙找到这所学校的所有可能的患者。

Input

输入文件包含多组数据。

对于每组测试数据:

第一行为两个整数n和m, 其中n是学生的数量, m是社团的数量。0 < n <= 30000,0 <= m <= 500。

接下来m行,每一行有一个整数k,代表社团中学生的数量。之后,有k个整数代表这个社团里每个学生的编号(在0到n-1之间)。

n = m = 0表示输入结束,不需要处理。

Output

对于每组测试数据, 输出可能的患者数目。

Sample Input

100 4
2 1 2
5 11 13 50 12 14
2 0 1
2 99 2
200 2
1 5
6 5 6 7 8 9 10
1 0
0 0

Sample Output

4
1
1

题解:这题少说了个条件,编号为0的学生固定为可疑患者。我们只要将每个社团中的人做一个连通图,再判断每个人的最终父亲节点是否与0号同学的节点相同即可。

代码:

#include <iostream>
#include <algorithm>
using namespace std;

int q[30001];
bool bb[30001];
inline int find(int a)
{
  if (q[a]!=a) q[a]=find(q[a]);//找节点同时更新父亲节点的值,减少时间
  return q[a];	
}

inline void jiehe(int x,int y)
{
  int d=find(x);int dd=find(y);//找最终父亲节点
  if (d==dd) return;//相同不用再结合
  if (d==0) q[dd]=q[d]; else q[d]=q[dd];//确保0的最终父亲节点是0	
}

inline void solute(int n,int m)
{
	int b[30001],f;
	for (int i=1;i<=n;i++) {q[i]=i;bb[i]=false;}//初始化每个学生都未曾出现。队列初始化
    for (int i=1;i<=m;i++)
	{
		cin >> f;
		for (int j=1;j<=f;j++)
		{
		  cin >> b[j];
		  bb[b[j]]=true;
		}		
		for (int j=2;j<=f;j++) 
		{
		  jiehe(b[1],b[j]);//作连通图
		}
	}
	int d=0;
	for (int i=0;i<=n;i++)
	if (bb[i]&&find(i)==q[0]) d++;//只有出现过的学生并且找到父亲节点与0号学生相同,计数
	cout << d << endl;	
}

int main()
{
	int n,m;
	cin >> n >> m;
	while(n!=0||m!=0)
	{
		solute(n,m);
		cin >> n >> m;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值