解题思路:这个题目和poj1182一样都是种类并查集的扩展应用,不过这个题中,并没有类的概念。我们做的时候就是把有关系的节点划分在一个集合。他们的关系是通过节点和他的父亲节点的距离来维系的。就像1182那题,关系是通过吃与被吃来维系一样。
我的看法:我开始做这题的时候,把题目意思理解为从一个栈一到另一个栈的移动,是按照出栈顺序来移动的,然后我做的时候就对每个节点添加了一个属性为moveTimes,每次union的时候,根节点的moveTimes++,然后叶节点的移动次数就是他的移动次数和他的所有祖先节点的移动次数累加。那么它到它父亲节点的距离根据移动次数的奇偶来确定是负数还是正数。它到根节点的距离就是它到父亲节点的距离加上父亲节点到根节点的距离和。但题目的意思是移动栈的时候是整体移动,那就更简单了,不用moveTimes这个属性了。
- Source Code
#include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; const int MAXSIZE = 30005; typedef struct node{ int dist; int father; int nodeNum; }Cube; Cube cube[MAXSIZE]; void init(){ for(int i = 1;i<MAXSIZE;i++){ cube[i].dist = 0; cube[i].father = i; cube[i].nodeNum = 1; } } int find(int x){ if(cube[x].father!=x){ int tmp = cube[x].father; cube[x].father = find(cube[x].father); cube[x].dist = cube[tmp].dist+cube[x].dist; } return cube[x].father; } void Union(int x,int y){ cube[x].father = y; cube[x].dist = cube[y].nodeNum; cube[y].nodeNum = cube[y].nodeNum+cube[x].nodeNum; } int main(){ int p; scanf("%d",&p); getchar(); init(); for(int i = 0;i<p;i++){ int ch = getchar(); int a,b; if(ch =='M'){ scanf("%d%d",&a,&b); int p = find(a); int q = find(b); if(p!=q){ Union(p,q); } } else if(ch == 'C'){ scanf("%d",&a); int p = find(a); cout<<cube[a].dist<<endl; } getchar(); } return 0; }
This is my previous code
#include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; const int MAXSIZE = 30005; typedef struct node{ int moveTimes; int dist; int father; int nodeNum; }Cube; Cube cube[MAXSIZE]; void init(){ for(int i = 1;i<MAXSIZE;i++){ cube[i].moveTimes = 0; cube[i].dist = 0; cube[i].father = i; cube[i].nodeNum = 1; } } int find(int x){ if(cube[x].father!=x){ int tmp = cube[x].father; cube[x].father = find(cube[x].father); cube[x].moveTimes+=cube[tmp].moveTimes-cube[cube[x].father].moveTimes; cube[x].dist = cube[tmp].dist+(cube[x].moveTimes%2 == 0?-1:1)*cube[x].dist; } return cube[x].father; } void Union(int x,int y){ cube[x].father = y; cube[x].moveTimes++; cube[x].dist = cube[x].nodeNum+cube[y].nodeNum-1; cube[y].nodeNum = cube[y].nodeNum+cube[x].nodeNum; } int main(){ int p; scanf("%d",&p); getchar(); init(); for(int i = 0;i<p;i++){ int ch = getchar(); int a,b; if(ch =='M'){ scanf("%d%d",&a,&b); int p = find(a); int q = find(b); if(p!=q){ Union(p,q); } } else if(ch == 'C'){ scanf("%d",&a); int p = find(a); cout<<cube[a].dist<<endl; } getchar(); } return 0; }