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 '是一维数组' ...
随机推荐
- DHCP工作过程的六个主要步骤
对于学习DHCP来说,很重要的一部分就是对于DHCP工作过程的理解. DHCP分为两个部分:一个是服务器端,另一个是客户端. 所有客户机的IP地址设定资料都由DHCP服务器集中管理,并负责处理客户端的 ...
- 用STS和Maven的方式创建一个JavaWeb项目
一.创建项目 1.Eclipse中用Maven创建项目,选maven-archetype-webapp,如下图: 创建好项目后,目录如下: 至此,项目已经创建完毕,下边是配置.关键所在!!! 二.项目 ...
- numpy中的np.random.mtrand.RandomState
1 RandomState 的应用场景概述 在训练神经网络时,苦于没有数据,此时numpy为我们提供了 “生产” 数据集的一种方式. 例如在搭建神经网络(一)中的 4.3 准备数据集 章节中就是采用n ...
- 基于matplotlib的数据可视化 - 三维曲面图gca
1 语法 ax = plt.gca(projection='3d')ax.plot_surface(x,y,z,rstride=行步距,cstride=列步距,cmap=颜色映射) gca(**kwa ...
- EasyUI 中GridView 满足某条件 改变行的背景色
<table id='grid' class='easyui-datagrid' style='width:1500px;height:450px' url='Ajax-index.php?mo ...
- MFC带标题栏的窗口和不带标题栏的窗口最大化
原文链接: http://blog.csdn.net/smartgps2008/article/details/7741223 不带标题栏的窗口最大化: 第一种情况:覆盖任务栏 ShowWindow( ...
- SharePoint 2013 Step by Step——使用自定义的List Template
Overview 对于企业员工来说,"扁平结构"的LIST是日常操作中经常使用到的,LIST的好处是方便数据的录入以及数据的整理分析,尤其是Quick Edit功能,可以实现快速编 ...
- Android 如何添加一个apk使模拟器和真机都编译进去 m
添加一个apk都需要将LOCAL_PACKAGE_NAME的值添加到PRODUCT_PACKAGES才行.而PRODUCT_PACKAGES一般在build/target/product/目录下的文件 ...
- activiti Task
UserTask ScriptTask ServiceTask MailTask ManualTask ReceiveTask BusinessRuleTask callActivity
- sqlite 判断表中是否包含 某个字段
数据库 都有一个 根表..(我的理解) 也就是 你创建了一个数据库 里面就带有 一个表 sqlite_master 字段有 type , name , tbl_name , rootpage ,sq ...