题意是n个人,m组数,每组数的第一个数k表示这组数有k个数,求所有与0直接或间接有关系的数。
建立它们之间的关系后,只要查询下最终的根是0的个数就行,当然两个数中只能最小的数当根。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int maxn = 3e4+10; 5 int fa[maxn], rank[maxn]; 6 int n, m; 7 int find(int x){ 8 if(x == fa[x])return x; 9 else return fa[x] = find(fa[x]); 10 } 11 void uni(int x, int y){ 12 x = find(x); 13 y = find(y); 14 if(x < y){ 15 fa[y] = x; 16 }else{ 17 fa[x] = y; 18 } 19 } 20 int main(){ 21 while(~scanf("%d",&n)&&n){ 22 scanf("%d",&m); 23 int ans = 0; 24 for(int i = 1; i < n; i ++){ 25 fa[i] = i; 26 rank[i] = 0; 27 } 28 for(int i = 1; i <= m; i ++){ 29 int a, b, c; 30 scanf("%d%d",&a,&b); 31 for(int i = 1; i < a; i ++){ 32 scanf("%d",&c); 33 uni(b, c); 34 } 35 } 36 for(int i = 0; i < n; i ++){ 37 if(find(i) == 0) ans ++; 38 } 39 printf("%d ",ans); 40 } 41 return 0; 42 }
题意是n个人中,给定一些人之间的关系,直接或间接有关系的一组,求最终有多少组。
并查集,求最终的根是本身的有多少。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int maxn = 1e3+10; 5 int fa[maxn]; 6 int find(int x){ 7 if(fa[x] == x)return x; 8 else return fa[x] = find(fa[x]); 9 } 10 void uni(int x, int y){ 11 x = find(x); 12 y = find(y); 13 if(x < y){ 14 fa[y] = x; 15 }else{ 16 fa[x] = y; 17 } 18 } 19 int main(){ 20 int t, n, m; 21 scanf("%d",&t); 22 while(t--){ 23 int ans = 0; 24 scanf("%d%d",&n,&m); 25 for(int i = 1; i <= n; i ++) fa[i] = i; 26 for(int i = 0; i < m; i ++){ 27 int a, b; 28 scanf("%d%d",&a,&b); 29 uni(a, b); 30 } 31 for(int i = 1; i <= n; i ++){ 32 if(fa[i] == i) ans ++; 33 } 34 printf("%d ",ans); 35 } 36 return 0; 37 }