戴好口罩

题意:

新型冠状病毒肺炎(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 } 

 

上一篇:python 多线程编程


下一篇:luoguP1361 小M的作物 最小割