现在的位置: 首页 > 综合 > 正文

POJ 1988 Cube Stacking || HDU 2818 Building Block

2019年02月25日 ⁄ 综合 ⁄ 共 1232字 ⁄ 字号 评论关闭

题目链接~~>

做题感悟:这题开始被吓到了,一看是多校练习赛,在 HDU 提交了 n 次都是栈溢出,但是在 POJ 1 A.(哪位大牛路过麻烦看一下挫代码为什么在POJ上可以过在HDU上过不了)真无语!!

解题思路:方法一、先说我的思路吧: 题意中 M x y  是把 y 接到 x的下面,最后求 x下面有多少个木块,其实可以转化为把y 放到x上面,进而求x上面有多少个。但是这样的话必须开两个并查集, 假如 M 1 6  M 2 4  M 2 6  查询C 4 答案为 2 可以用一个并查集fa[] fa[1‘]=6’ (1‘,6'均指其父亲) fa[2']=4' (这个并查集起主要作用)如果你要实现 M
2 6 必须找到2的父亲和6的最小的孙子让6最小的孙子成为2父亲的父亲(简单说就是让2的父亲接在6的孙子后面),至于查询的时候 执行一次并查集就可以得到x上面有多少个(题中是下面有多个).

                方法二、其实可以用一个数组记录节点总的个数(这样HDU可以过)其它上面的差不多具体见这里~>.

代码:

#include<stdio.h>
#include<iostream>
#include<map>
#include<stack>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue> 
#include<algorithm>
using namespace std ;
#define LEN sizeof(struct node)
const double PI = 3.1415926 ;
const double INF = 99999999 ;
const int MX =30005 ;
int fa[MX],fb[MX],num[MX] ;
int FA(int x)
{
   if(fa[x]!=x)
   {
        int y=FA(fa[x]) ;
        num[x]+=num[fa[x]] ;// 更新权值
        return  fa[x]=y ;
   }
   else  return  x ;
}
int FB(int x) // 寻找子节点
{
    return fb[x]==x ? x : fb[x]=FB(fb[x]) ;
}
void init() // 初始化
{
    for(int i=0 ;i<=30001 ;i++)
    {
        fa[i]=i ;
        fb[i]=i ;
        num[i]=0 ;
    }
}
int main()
{
    char ch ;
    int m,x,y,ax,ay ;
    scanf("%d",&m) ;
    init() ;
    for(int i=0 ;i<m ;i++)
    {
        cin>>ch ;
        if(ch=='M')
        {
            scanf("%d%d",&x,&y) ;
            if(x!=y)
            {
                ax=FA(x) ; // 找子节点 
                ay=FB(y) ; // 找父亲节点 
                if(ax!=ay)
                {
                   fa[ax]=ay ;  // 用于查询
                   num[ax]++ ;  // 不要忘记!!
                   fb[ay]=ax ;
                }
             }
        }
        else
        {
            scanf("%d",&x) ;
            FA(x) ;
            printf("%d\n",num[x]) ;
        }
    }
    return 0 ;
}

 

 

 

 

 

抱歉!评论已关闭.