poj1988(判断一个结点下面有多少个结点,推荐)
题意:有n个元素,开始每个元素自己一栈,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈。第二种操作是询问含有x元素下面有多少个元素。
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
输出:
1
0
2 思路:这道题,说不上很难,额,解决它也的确花了比较长的时间。询问x元素下面有多少个元素,那么我只需要统计x元素上面有多少个元素,再用x所在的并查集的根节点的元素个数减去x元素上面的元素个数,
结果就出来了......当然,还是有些细节地方要说说的,在路径压缩的时候,有个rang[][3],其中rank[x][0],代表元素x上面有多少个元素,rank[x][1]代表元素x下面有多少个元素,rank[x][2]判断x元素
是否为某个子并查集的根节点。
如果某个结点x的父亲结点y曾经为某一个子并查集的根节点,那么,说明对于这个结点x已经是在y为根节点的时候压缩过了,那么当y不为根节点了,就不必再重新x对y的路径了,只需要直接更新,x对于新的根节点的路径
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int father[30005],rank[30005][3];
int flag=0;
int find(int x)
{
if(rank[x][0]==0)
rank[x][2]=1;
if(x==father[x])
return x;
int tmp=father[x];
father[x]=find(father[x]);
int root=father[x];
if(tmp==root)
{
rank[root][1]+=rank[x][1];
rank[x][1]=0;
//if(rank[root])
/*if(flag==1)
{
printf("1: %d %d %d %d\n",x,tmp,rank[x][0],rank[tmp][0]);
}*/
}
else
{
rank[root][1]+=rank[x][1];
rank[x][1]=0;
if(rank[tmp][2]==1) //曾经为某一颗子并查集的根结点,那么它下面的结点直接+上根节点的值就是
rank[x][0]+=rank[tmp][0];
else
rank[x][0]=rank[tmp][0]+1;
/*if(flag==1)
{
printf("2: %d %d %d %d\n",x,tmp,rank[x][0],rank[tmp][0]);
}*/
}
return root;
}
void liantong(int tmp,int tmp1)
{
int x=find(tmp);
int y=find(tmp1);
father[y]=x;
rank[y][0]=rank[x][1];
rank[x][1]+=rank[y][1];
rank[y][1]=0;
}
int main()
{
int n;
scanf("%d",&n);
{
for(int i=0; i<=30001; i++)
{
father[i]=i;
rank[i][0]=0;
rank[i][1]=1;
rank[i][2]=0;
}
while(n--)
{
char ch[10];
scanf("%s",ch);
if(ch[0]=='M')
{
int tmp,tmp1;
scanf("%d%d",&tmp,&tmp1);
int x=find(tmp);
int y=find(tmp1);
if(x!=y)
liantong(tmp,tmp1);
// find(tmp);
// find(tmp1);
}
else
{
int k;
scanf("%d",&k);
if(k==17)
flag=1;
int ans=rank[find(k)][1];
/*if(rank[k][0]==0)
printf("%d\n",rank[k][1]-1);
else*/
printf("%d\n",ans-rank[k][0]-1);
}
}
}
return 0;
}
/*
110
M 12 14
M 15 16
M 16 17
M 12 17
C 17
*/
poj1988(判断一个结点下面有多少个结点,推荐)的更多相关文章
- Trailing Zeroes (III) 假设n!后面有x个0.现在要求的是,给定x,要求最小的n; 判断一个n!后面有多少个0,通过n/5+n/25+n/125+...
/** 题目:Trailing Zeroes (III) 链接:https://vjudge.net/contest/154246#problem/N 题意:假设n!后面有x个0.现在要求的是,给定x ...
- pta 奇数值结点链表&&单链表结点删除
本题要求实现两个函数,分别将读入的数据存储为单链表.将链表中奇数值的结点重新组成一个新的链表.链表结点定义如下: struct ListNode { int data; ListNode *next; ...
- C/C++中创建(带头结点、不带头结点的)单链表
1.带头结点的单链表(推荐使用带头结点的单链表)(采用尾插法) 了解单链表中节点的构成 从上图可知,节点包含数据域和指针域,因此,在对节点进行定义时,我们可以如下简单形式地定义: /* 定义链表 */ ...
- Android 判断一个 View 是否可见 getLocalVisibleRect(rect) 与 getGlobalVisibleRect(rect)
Android 判断一个 View 是否可见 getLocalVisibleRect(rect) 与 getGlobalVisibleRect(rect) [TOC] 这两个方法的区别 View.ge ...
- excel批处理_判断一个名称是不是药品
把药品名称导入到sheet1的A字段 # -*- coding: utf-8 -*-"""Created on Fri Dec 9 09:38:58 2016判断一个名 ...
- 判断一个字符串str不为空的方法
1.str == null; 2."".equals(str); 3.str.length 4.str.isEmpty(); 注意:length是属性,一般集合类对象拥有的属性,取 ...
- Android 如何判断一个应用在运行(转)
Android 如何判断一个应用在运行 在一个应用中,或一个Service .Receiver中判断一个应用是否正在运行,以便进行一些相关的处理. 这个时候我们需要得到一个ActivityManag ...
- ZOJ Problem Set - 1331 Perfect Cubes 判断一个double是否为整数
zju对时间要求比较高,这就要求我们不能简单地暴力求解(三个循环搞定),就要换个思路:因为在循环时,已知a,确定b,c,d,在外重两层循环中已经给定了b和c,我们就不用遍历d,我们可以利用d^3=a^ ...
- PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?
如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...
随机推荐
- MYSQL IN 与 EXISTS 的优化示例介绍
优化原则:小表驱动大表,即小的数据集驱动大的数据集. ############# 原理 (RBO) ##################### select * from A where id in ...
- 利用hadoop来解决“共同好友”的问题
假设A有好友B C D:B有好友A C D E:C有好友A B D E:D有好友A B C E;E有好友B C D. A -> B C D B -> A C D E C -> A B ...
- block(五)用法
最近又从网上找了点block用法的博客,供大家参考. Block简介: Block的实际行为和Function很像,最大的差别是在可以存取同一个Scope的变量值.Block实体形式如下: ^(传入参 ...
- git log退出方法
英文状态下按Q
- Android逆向之旅---破解"穿靴子的猫"游戏的收费功能
一.游戏收费分析 游戏收费非常正常的,可是玩游戏最恶心的就是你还没玩就要充值,非常恼火,事实上我不怎么玩游戏,主要是给小孩子们弄,比方如今好多小屁孩们喜欢玩水果忍者这个游戏.可是这个游戏在没有開始玩的 ...
- Java Nashorn--Part 3
jjs 的 -Scripting 选项 jjs shell 是一个不错的方法来测试一些基本的 JavaScript,或者于不太熟悉的 JavaScript包进行交互(主要是指 javax.script ...
- Android_ViewPager_实现多个图片水平滚动
1.示意图 2.实现分析 (1).xml配置 <!-- 配置container和pager的clipChildren=false, 并且指定margi ...
- [转]PostgreSQL源码结构
PostgreSQL采用C/S(客户机/服务器)模式结构.应用层通过INET或者Unix Socket利用既定的协议与数据库服务器进行通信. 另外,还有一种‘Standalone Backend’使用 ...
- 向量运算 与 JavaScript
二维向量都包含两个值:方向(direction)及大小(magnitude) 这两个值可以表达出各种各样的物理特性来,比如力和运动.如两个物体间的碰撞检测. 向量的大小 虽说二维向量是对大 ...
- 尼康G镜头与D镜头的差别
尼康系统实现自动对焦必须:机身和镜头,两者至少其一拥有马达. 尼康现在新出的G头,几乎都带马达.但在胶片时代的G头,几乎都不带马达. G只表示:没有手动光圈环. D只表示:镜头能提供距离信息给机身. ...