标签:glob NPU ios find when tac math init using
Input
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
翻译:有n个人,m个集合,每个人的标号为0到n,其中0带有传染病,如果再一个集合中有人有传染病,那么这个集合里的所有人都会有这种传染病
,问每个测试中有传染病的有但是人,输入第一行为n,m。往下为m行,每行第一个为该集合的人数,其他为该集合中人的标号。输入以0 0结束。
思路:简单的并查集,套用模板即可,结果只需判断与0同集合的有但是人。
代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //fa[x]表示x的最远祖先 22 int fa[30005]; 23 //初始化,一开始每个点单独成集合 24 void build(int qwq) 25 { 26 for(int i=0;i<=qwq;i++) 27 { 28 fa[i]=i; 29 } 30 return ; 31 } 32 //找到x的最远祖先,并且压缩路径 33 int find(int x) 34 { 35 if(fa[x]==x) 36 { 37 return x; 38 } 39 return fa[x]=find(fa[x]); 40 } 41 //判断x,y是不是在同一个集合里,直接判断最远祖先是不是一样的 42 bool che(int x,int y) 43 { 44 return find(x)==find(y); 45 } 46 //合并x,y,我们在判断x和y是不是同一个集合里, 47 //路径压缩之后fa[x],fa[y]已经是最远祖先了, 48 //所以直接将fa[x]的父亲连接在fa[y]的祖先上 49 void mer(int x,int y) 50 { 51 if(!che(x,y)) 52 { 53 fa[fa[x]]=fa[y]; 54 } 55 return ; 56 } 57 58 int main() 59 { 60 int n,m; 61 while(scanf("%d %d",&n,&m)&&(n||m)) 62 { 63 //初始化 64 build(n); 65 int k,a,b; 66 for(int i=0;i<m;i++) 67 { 68 scanf("%d",&k); 69 //每组第一个数 70 scanf("%d",&a); 71 //将每组其他数与本组的第一个数合并 72 for(int j=1;j<k;j++) 73 { 74 scanf("%d",&b); 75 mer(a,b); 76 } 77 } 78 //0本身也是一个人 79 int ans=1; 80 //遍历寻找与0同集合的数 81 for(int i=1;i<=n;i++) 82 { 83 if(find(i)==find(0)) 84 { 85 ans++; 86 } 87 } 88 printf("%d\n",ans); 89 } 90 }
The Suspects POJ - 1611 并查集,同集合的数
标签:glob NPU ios find when tac math init using
原文地址:https://www.cnblogs.com/mzchuan/p/11594195.html