题意:
新型冠状病毒肺炎(Corona Virus Disease 2019,COVID-19),简称“新冠肺炎”,是指2019新型冠状病毒感染导致的肺炎。
如果一个感染者走入一个群体,那么这个群体需要被隔离!
小A同学被确诊为新冠感染,并且没有戴口罩!!!!!!
危!!!
时间紧迫!!!!
需要尽快找到所有和小A同学直接或者间接接触过的同学,将他们隔离,防止更大范围的扩散。
众所周知,学生的交际可能是分小团体的,一位学生可能同时参与多个小团体内。
请你编写程序解决!戴口罩!!
Input
多组数据,对于每组测试数据:
第一行为两个整数n和m(n = m = 0表示输入结束,不需要处理),n是学生的数量,m是学生群体的数量。0 < n <= 3e4 , 0 <= m <= 5e2
学生编号为0~n-1
小A编号为0
随后,m行,每行有一个整数num即小团体人员数量。随后有num个整数代表这个小团体的学生。
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
我的题解:
并查集:对于“一类”元素,以某一个元素作为代表元,形成不同的类别的集合。
查:查找对应的代表元 即可确定某种属性
并:通过查判断是否是同一类元素,然后判断是否合并为一类元素。
集:将若干个元素分门别类,形成以有代表元的集合。
本题只需要计算与传染源相关联的群体人员数目,是简单的并查集问题。
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 7 const int maxn=100005; 8 int n,maxL,maxlen,f1,f2; 9 int L1[maxn],L2[maxn]; 10 int u,w; 11 typedef struct node{ 12 int u,v,w,nxt; 13 }Edge; 14 Edge Edges[maxn]; 15 int head[maxn],tot,vis[maxn]; 16 17 void addEdge(int u,int v,int w){ 18 Edges[tot].u=u; 19 Edges[tot].v=v; 20 Edges[tot].w=w; 21 Edges[tot].nxt=head[u]; 22 head[u]=tot; 23 tot++; 24 } 25 26 void dfs(int u,int *a,int L){ 27 a[u]=L; 28 if(maxL<L) { 29 maxL=L;maxlen=u; 30 } 31 for(int i=head[u];i!=-1;i=Edges[i].nxt){ 32 if(!vis[Edges[i].v]){ 33 vis[Edges[i].v]=true; 34 dfs(Edges[i].v, a, L + Edges[i].w); 35 } 36 } 37 } 38 int main(){ 39 while(cin>>n){ 40 41 tot=0; 42 for(int i=0;i<n+2;++i) head[i]=-1; 43 44 for(int i=2;i<=n;++i){ 45 cin>>u>>w; 46 addEdge(i,u,w); 47 addEdge(u,i,w); //加入双向边 48 } 49 50 memset(vis,0,sizeof(vis)); 51 maxL=-1;vis[1]=1; 52 53 dfs(1,L1,0); 54 f1=maxlen; 55 memset(vis,0,sizeof(vis)); 56 maxL=-1; 57 vis[f1]=1; 58 59 dfs(f1,L1,0); 60 f2=maxlen; 61 memset(vis,0,sizeof(vis)); 62 vis[f2]=1; 63 dfs(f2,L2,0); 64 65 for(int i=1;i<=n;i++){ 66 cout<<max(L1[i],L2[i])<<endl; 67 //较大者即为输出 68 } 69 } 70 return 0; 71 }