HDU 3635 Dragon Balls
题解:做到一种并查集的新题型,在状态压缩的时候传递祖先的信息,每个根结点都是最多移动一次的,所以记录移动次数把自己的加上父亲结点的就是移动总数了。
#include <cstdio> #include <cstring> const int MAXN=10010; int n,q,count[MAXN],f[MAXN],move[MAXN]; int sf(int x){ if(f[x]==x) return x; int t=f[x]; f[x]=sf(f[x]); move[x]+=move[t]; return f[x]; } void Union(int x,int y){ x=sf(x); y=sf(y); if(x!=y){ f[x]=y; count[y]+=count[x]; move[x]=1; } } int main(){ int T; scanf("%d",&T); int cas=1; while(T--){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++)count[i]=1; for(int i=1;i<=n;i++)f[i]=i; memset(move, 0, sizeof(move)); char str[10]; printf("Case %d:\n",cas++); for(int i=1;i<=q;i++){ scanf("%s",str); if(str[0]=='T'){ int x,y; scanf("%d%d",&x,&y); Union(x,y); } else{ int x; scanf("%d",&x); int fx=sf(x); printf("%d %d %d\n",fx,count[fx],move[x]); } } } return 0; }
愿你出走半生,归来仍是少年