HDU 3635 Dragon Balls
一个他们所谓“简单”的并查集,伤了我两天!
/*
我感觉这个题,刚开始题意、更准确的说是题的情景,没有清楚的搞明白!!
题的情景分析清的话,你会发现该题出的是多么简单,它的限制是多么狠!!
要说难点在那?那就是他要求的运输次数……这个次数如何去算,在递归中如何构造关系式?
*/注释为废话,不是主题
#include <stdio.h> #include <string.h> #define N 10002 int ancestor[N],rank[N]; int count[N]; void Sinit(int n) { for(int i=1;i<=n;i++) ancestor[i]=i,count[i]=0,rank[i]=1; } int Sfind(int x) { int ancex=ancestor[x]; if(ancestor[ancex]!=ancestor[x]) { ancestor[x]=Sfind(ancex); count[x]+=count[ancex]; } //return ancex;//记录这一刻 return ancestor[x]; } void Sunion(int x,int y) { int ancex=ancestor[x],ancey=ancestor[y]; rank[ancey]+=rank[ancex]; rank[ancex]=0; ancestor[ancex]=ancey; count[ancex]++; } int main() { //freopen("input.txt","r",stdin); int t,n,m; int ind=0; int x,y; char c[2]; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); printf("Case %d:\n",++ind); Sinit(n); for(int i=0;i<m;i++) { //getchar(); scanf("%s",c); if(c[0]=='T') { scanf("%d %d",&x,&y); Sfind(x); Sfind(y); Sunion(x,y); } else { scanf("%d",&x); Sfind(x); printf("%d %d %d\n",ancestor[x],rank[ancestor[x]],count[x]); //memset(count,0,sizeof(count)); } } } return 0; }
记录这一刻: int Sfind(int x) { int ancex=ancestor[x]; if(ancestor[ancex]!=ancestor[x]) { ancestor[x]=Sfind(ancex); count[x]+=count[ancex];//这里的问题...!!! } return ancex;//记录这一刻 } 我返回的是ancex,不是ancestor[x];要知道返回ancex,不是根节点!