Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 21402 | Accepted: 7492 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
Sample Output
1 0 2
//好题::运用并查集 /*题意:: 有N个立方体(筛子),从1到N编号,现在用这些立方体(筛子)做一个游戏 输入一个t,表示有几行,再输入一个字符,若字符是‘M’,则输入两个数,表示两个筛子的编号x,y,表示将 x放到y上面 ,若字符为‘C’,则输入一个数,表筛子编号,然后输出这个筛子下面有几个筛子。*/ //例如::输入样例(这块看了半天没看懂) /* M 1 6 表示将1放到6上面 1 6 C 1 表示输出1下面有几个数,很容易看出有一个 M 2 4 表示将2放到4上 2 4 M 2 6 ***这块重点,表示将2放到6上 2 他每次输入都是连续的,即使有输出也不会中断,直到输入的行数等于 t 。 4 1 6 C 4 表示4下面有几个数,可以看出有2个。*/ //集体解题思路见代码 <pre class="cpp" name="code">#include<stdio.h> #include<string.h> #include<math.h> int a[30110]; int b[30110];//记录从该节点到最后节点的深度 int s[30110];//记录节点所处的深度 int find(int x) { if(x!=a[x]) { int t=a[x]; a[x]=find(a[x]); s[x]+=s[t]; } return a[x]; } int marge(int x,int y) { int fx,fy; fx=find(x); fy=find(y); if(fx!=fy) { a[fy]=fx; s[fy]=b[fx];//这块是重点,自己多找几个点模拟一下就清楚了 b[fx]+=b[fy]; } } int main(){ int t; while(scanf("%d",&t)!=EOF) { int i,x,y; char c; for(i=0;i<=30000;i++) { a[i]=i; b[i]=1; s[i]=0; } while(t--) { getchar(); scanf("%c",&c); if(c=='M') { scanf("%d%d",&x,&y); marge(x,y); } else { scanf("%d",&x); int dx=find(x);//找到根节点 printf("%d\n",b[dx]-s[x]-1);//从根节点到要找的节点间的节点数 } } } return 0; }