题解:并查集,这里要用路径压缩来优化
代码:// 这里范围理错了, 浪费20分钟debug
#include <set> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int maxn=10010; int fa[maxn]; int n; int Find(int x) { // int temp=x; while(fa[temp]!=temp) { temp=fa[temp];// } while(fa[x]!=temp) // 路劲压缩 { int zz=fa[x]; fa[x]=temp; x=zz; } return temp; // root } void Merge(int x,int y) { int fx=Find(x);// root of x int fy=Find(y);// root of y if(fx != fy) { fa[fx] = fy; } } int main() { cin>>n; int pre,now; set<int >st; for(int i=1;i<maxn;i++) fa[i]=i; for(int i=1;i<=n;i++) { int k; cin>>k; for(int j=1;j<=k;j++) { if(j==1) { scanf("%d",&now); } else { pre=now; // cout<<"pre:"<<pre<<endl; scanf("%d",&now); Merge(pre,now);// // cout<<fa[2]<<endl; // cout<<pre<<' '<<now<<' '<<fa[pre]<<' '<<fa[now]<<endl; } st.insert(now); } } int q; cin>>q; int num=0; for(int i=1;i<=st.size();i++) { if(fa[i]==i) { num++; // cout<<i<<endl; } } cout<<st.size()<<" "<<num<<endl; while(q--) { int a,b; scanf("%d %d",&a,&b); int fa=Find(a); int fb=Find(b); if(fa==fb) cout<<"Y"<<endl; else cout<<"N"<<endl; } // for(int i=1;i<=st.size();i++) cout<<fa[i]<<" "; // cout<<fa[2]<<endl; return 0; }