如题。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> using namespace std; /* 并查集水题 */ const int maxn=10000+5; struct UF{ int father[maxn]; void init(){ for(int i=0;i<maxn;i++) father[i]=i; } int find_root(int x){ if(father[x]!=x){ father[x]=find_root(father[x]); } return father[x]; } void Union(int x,int y){ int fx=find_root(x); int fy=find_root(y); if(fx!=fy){ father[fy]=fx; } } }uf; int main() { int n,q; int k,a,b; int vis[maxn]; uf.init(); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d %d",&k,&a); vis[a]=1; for(int j=1;j<k;j++){ scanf("%d",&b); vis[b]=1; uf.Union(a,b); a=b; } } int flag[maxn]; memset(flag,0,sizeof(flag)); int cnt=0; for(int i=0;i<maxn;i++){ if(vis[i]){ cnt++; int fa=uf.find_root(i); flag[fa]=1; } } int tree=0; for(int i=0;i<maxn;i++){ tree+=flag[i]; } printf("%d %d ",tree,cnt); scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d %d",&a,&b); int fa=uf.find_root(a); int fb=uf.find_root(b); if(fa==fb) printf("Yes "); else printf("No "); } return 0; }