第一道并查集,47ms ,还是很慢啊,不过是绞尽脑汁,调试了n次,做出来的,思路还是挺清晰地
#include <iostream> using namespace std; const int maxn=30010; int parent[maxn]; int amount[maxn]; int rank[maxn]; int n,m; void init() { for(int i=0;i<n;i++) { parent[i]=i; amount[i]=1; rank[i]=0; } } int find(int t) { if(parent[t]!=t) return(find(parent[t])); return t; } void Union(int r1,int r2) { if(rank[r1]>rank[r2]) { parent[r2]=r1; amount[r1]+=amount[r2]; } else { parent[r1]=r2; amount[r2]+=amount[r1]; if(rank[r1]==rank[r2]) rank[r2]++; } } int main() { while(scanf("%d%d",&n,&m)&&!(n==0&&m==0)) { init(); int i,j=0,g,f,r1,r2,t; for(i=0;i<m;i++) { cin>>g; if(g) { cin>>f; for(j=1;j<g;j++) { cin>>t; r1=find(f); r2=find(t); if(r1!=r2) { Union(r1,r2); } } } } int outcome=find(0); cout<<amount[outcome]<<endl; } return 0; }