UVA

来源:互联网 发布:蜘蛛纸牌算法 编辑:程序博客网 时间:2024/06/05 10:33

题意是需要写一个不相交集,有三种操作,第一种是,把包含片p和q元素的集合合并,如果p、q在同一集合,则忽视这个操作

第二种操作是把p加入到q所在的集合,如果p、q在同一集合,则忽视这个操作

第三中操作,输出p所在集合的元素个数与元素和。


第一种操作直接用并查集的合并即可,第三中操作用一个sum数组和size数组储存即可。

麻烦的是第二种操作,直接合并p和q的话是不可取的,需要把这个p从原有集合中删除,然后把这个点的信息插入末尾,此时需要一个数组real来存储所有元素的真实编号,然后在与q合并。


#include<stdio.h>int pre[200002];int size[200002];int sum[200002];int real[100002];int cnt;int find(int x){if(x==pre[x]) return x;else{pre[x]=find(pre[x]);return pre[x];}}int main(void){int n,m;int o,p,q;while(scanf("%d%d",&n,&m)!=EOF){cnt=n;for(int i=1;i<=n;i++){    pre[i]=i;    real[i]=i;    sum[i]=i;    size[i]=1;}for(int i=1;i<=m;i++){      scanf("%d",&o);  if(o==1){  scanf("%d%d",&p,&q);  int tx=find(real[p]),ty=find(real[q]);          if(tx!=ty)          {          pre[tx]=ty;          sum[ty]+=sum[tx];          size[ty]+=size[tx];          }  }  else if(o==2){    scanf("%d%d",&p,&q);    int tx=find(real[p]),ty=find(real[q]);          if(tx!=ty){                    sum[tx]-=p;                size[tx]--;                    real[p]=(++cnt);                    pre[real[p]]=ty;                sum[ty]+=p;                size[ty]++;              }          }  else{  scanf("%d",&p);  int fp=find(real[p]);  printf("%d %d\n",size[fp],sum[fp]);  }  }   }} 

原创粉丝点击