Cube Stacking USACO 2004 Open 题解 并查集的超经典应用

来源:互联网 发布:吴昕淘宝店铺网址 编辑:程序博客网 时间:2024/06/04 20:07

      并查集的路径压缩的三种实现方法。

//刘汝佳经典飘逸骚气风格版本(缺点,有权值的时候权值不能紧跟着压缩)int find(int i){return f[i]==i?i:f[i]=find(f[i]);}//普通版本int find(int i){if(f[i]==i){return i;}else{return f[i]=find(f[i]);}}//有权值的路径压缩int find(int i){if(f[i]==i){return i;}else{int tmp=find(f[i]);quan[i]+=quan[f[i]];return f[i]=tmp;}}   


//------------------------------------------------------------------------------------------------------------------------------------------

     从题目中我们隐隐约约的读出了一点并查集的意思,所以想到用并查集来维护积木之间的关系。

   我们设计两个数组维护方块之间的关系,令ct数组表示集合中的元素个数,before数组表示元素i的上面有多少个元素,则题目中求元素i的下面有多少元素可以表示为:

ct[i]-before[i]-1   


#include<cstdio>#include<iostream>using namespace std;const int maxn=30005;int p,x,y;char c;int before[maxn],f[maxn],ct[maxn];int find(int i){if(f[i]==i){return i;}else{int tmp=find(f[i]);before[i]+=before[f[i]];return f[i]=tmp;}}int main(){for(int i=1;i<=maxn;i++){f[i]=i;ct[i]=1;}scanf("%d",&p);for(int t=1;t<=p;t++){cin>>c;if(c=='M'){scanf("%d%d",&x,&y); int px=find(x);int py=find(y);f[py]=px;before[py]+=ct[px];ct[px]+=ct[py];}else{scanf("%d",&x);int tmp=find(x);printf("%d\n",ct[tmp]-before[x]-1);}}return 0;}





原创粉丝点击