#include <iostream> #include <string.h> #include <string> #include <fstream> #include <algorithm> #include <stdio.h> #include <vector> #include <queue> #include <set> #include <cmath> using namespace std; const double eps = 1e-8; const double pi=acos(-1.0); const int INF=0x7fffffff; unsigned long long uINF = ~0LL; #define MAXN 100007 #define mod 1000000007 typedef long long LL; int pb[MAXN],pa[MAXN],num[MAXN],sum[MAXN]; int findset(int x) { return pa[x]!=x?pa[x]=findset(pa[x]):x; } int n,m; void print() { for(int i=1;i<=n;i++) cout<<pb[i]<<' '; for(int i=1;i<=n;i++) cout<<pa[i]<<' '; cout<<endl; for(int i=1;i<=n;i++) cout<<num[i]<<' '; cout<<endl; for(int i=1;i<=n;i++) cout<<sum[i]<<' '; cout<<endl; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { int t,p,q,x,y,x1,y1; for(int i=1;i<=n;i++) { pa[i]=i;pb[i]=i; num[i]=1; sum[i]=i; } for(int i=0;i<m;i++){ scanf("%d",&t); if(t==1){scanf("%d%d",&p,&q); x=pb[p];y=pb[q]; if(x==y)continue; x1=findset(x);y1=findset(y); if(x1==y1)continue; pa[x1]=y1; num[y1]+=num[x1]; sum[y1]+=sum[x1]; num[x1]=0; sum[x1]=0; } else if(t==2){scanf("%d%d",&p,&q); x=pb[p];y=pb[q]; if(x==y)continue; x1=findset(x);y1=findset(y); if(x1==y1)continue; pb[p]=y; num[y1]++; sum[y1]+=p; num[x1]--; sum[x1]-=p; } else if(t==3){scanf("%d",&p); printf("%d %d ",num[findset(pb[p])],sum[findset(pb[p])]);} //print(); } } return 0; }
带删除的并查集~ 实际上就是再开个数组保存对应并查集的下标