Description
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
分析:基础并查集。
解法一:
#include <iostream> #include <vector> using namespace std; int N,M; vector<int> par; vector<int> rank; void init(int n){ par.clear(); rank.clear(); par.resize(n); rank.resize(n); for(int i=0; i<n; i++){ par[i] = i; rank[i] = 0; } } int find(int x){ if(par[x]==x){ return x; }else{ return par[x] = find(par[x]); } } void unite(int x, int y){ x = find(x); y = find(y); if(x==y) return; if(rank[x] < rank[y]){ par[x] = y; }else{ par[y] = x; if(rank[x]==rank[y]) rank[x]++; } } bool same(int x, int y){ return find(x)==find(y); } int main(){ int i; while(scanf("%d%d",&N,&M)){ if(N==0 && M==0) break; init(N); int num, t; int first; for(int j=0; j<M; j++){ scanf("%d",&num); for(i=0; i<num; i++){ scanf("%d",&t); if(i==0){ first = t; } unite(first,t); } } int cnt = 0; for(i=0; i<N; i++){ if(same(0,i)){ cnt++; } } printf("%d\n",cnt); } return 0; }
解法二:
#include <iostream> #include <vector> using namespace std; int N,M; vector<int> par; vector<int> num; void init(int n){ par.clear(); num.clear(); par.resize(n); num.resize(n); for(int i=0; i<n; i++){ par[i] = i; num[i] = 1; } } int find(int x){ if(par[x]==x){ return x; }else{ return par[x] = find(par[x]); } } void unite(int x, int y){ x = find(x); y = find(y); if(x==y) return; if(num[x] <= num[y]){ par[x] = y; num[y] += num[x]; }else if(num[x] > num[y]){ par[y] = x; num[x] += num[y]; } } bool same(int x, int y){ return find(x)==find(y); } int main(){ int i; while(scanf("%d%d",&N,&M)){ if(N==0 && M==0) break; init(N); int cnt, t; int first; for(int j=0; j<M; j++){ scanf("%d",&cnt); for(i=0; i<cnt; i++){ scanf("%d",&t); if(i==0){ first = t; } unite(first,t); } } printf("%d\n",num[find(0)]); } return 0; }