方案数 = 连通块数 - 1;
https://vjudge.net/problem/CodeForces-277A/origin
#include<bits/stdc++.h>
using namespace std;
int n,m;
int s[110];
int height[110];
void init_set()
{
for(int i=1;i<=n;i++)
{
s[i]=i;
height[i]=0;
}
}
int find_set(int x)
{
if(x!=s[x])
{
s[x] = find_set(s[x]);
}
return s[x];
}
void merge_set(int x,int y)
{
x = find_set(x);
y = find_set(y);
if(height[x]==height[y])
{
height[x]+=1;
s[y]=x;
}
if(height[x]<height[y])
{
s[x] = y;
}else
{
s[y] = x;
}
}
vector<int> q[110];
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
cin>>n>>m;
init_set();
bool flag=0;
for(int i=1;i<=n;i++)
{
int num,x;
cin>>num;
if(num!=0) flag=1;
while(num--)
{
cin>>x;
q[x].push_back(i);
}
}
if(flag==0)
{
cout<<n<<endl;
return 0;
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<q[i].size();j++)
{
merge_set(q[i][0],q[i][j]);
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(i==s[i])
{
ans++;
}
}
cout<<ans-1<<endl;
return 0;
}