POJ1988 Cube Stacking

解题思路:这个题目和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;
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值