当前位置: 首页 > news >正文

温州网站制作建设郑州网

温州网站制作建设,郑州网,服装设计怎么学,廊坊建设公司网站作用 快速的处理以下问题:【近乎O(1)的时间完成】 1.将两个集合合并 2.询问两个元素是否在一个集合中 用树的形式维护集合 基本原理 每一个集合用一棵树表示 每一个集合的编号就是根结点的编号,对于每一个结点,都存储其父结点&#xf…

作用

快速的处理以下问题:【近乎O(1)的时间完成】

1.将两个集合合并

2.询问两个元素是否在一个集合中

用树的形式维护集合

基本原理

每一个集合用一棵树表示

每一个集合的编号就是根结点的编号,对于每一个结点,都存储其父结点,p[x]表示x的父结点,即p[x]=a表示编号为x的结点的父结点的编号为a

求某个点属于哪个集合时,就先找其父结点,如果其父结点不是根结点,那么就继续找其父结点的父结点,直到找到其根结点为止

问题1

如何判断树根:if(p[x]==x)

问题2

如何求x的集合编号:while(p[x]!=x) x=p[x];【只要x不是树根,就一直往上走,直到找到树根为止】

该步骤时间复杂度仍然很高,需要进行以下优化:

路径压缩:一旦找到根结点,就会把整个路径上所有点都指向根结点。【基本O(1)】

安秩合并【一般不用】

问题3

如何合并两个集合:px是x集合的集合编号【即x集合的根节点的编号是px】,py是y集合的集合编号【即y集合的根节点的编号是py】 p[px]=py或p[py]=px

代码实现

int find(int x) {//返回x所在集合的编号+路径压缩

if (p[x] != x)

p[x] = find(p[x]);

return p[x];

}

例题——合并集合

一共有n个数,编号是1~n,最开始每个数各自在一个集合中。

现在要进行m个操作,操作共有两种:

“M a b”,将编号为a和b的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;

“Q a b”,询问编号为a和b的两个数是否在同一个集合中;

输入格式

第一行输入整数n和m。

接下来m行,每行包含一个操作指令,指令为“M a b”或“Q a b”中的一种。

输出格式

对于每个询问指令”Q a b”,都要输出一个结果,如果a和b在同一集合内,则输出“Yes”,否则输出“No”。

每个结果占一行。

数据范围

1≤n,m≤105

输入样例

4 5

M 1 2

M 3 4

Q 1 2

Q 1 3

Q 3 4

输出样例

Yes

No

Yes

代码

#include<iostream>

using namespace std;

const int N = 100010;

int p[N];//存储父结点

int n, m;

int find(int x) {//返回x所在集合的编号+路径压缩

if (p[x] != x)

p[x] = find(p[x]);

return p[x];

}

int main() {

scanf("%d%d", &n, &m);

for (int i = 1;i <= n;i++)

p[i] = i;

while (m--) {

char op[2];//因为在使用scanf进行读取时,若读取单个字符会读取到空格、回车等其他字符,使用scanf读取字符串时可忽略空格、回车等其他字符

int a, b;

scanf("%s%d%d", op, &a, &b);

if (op[0] == 'M')

p[find(a)] = find(b);//合并

//find(a)返回a的祖宗结点,find(b)返回b的祖宗结点,让a的祖宗结点的父结点等于b的祖宗结点

else {

if (find(a) == find(b))

puts("Yes");

else

puts("No");

}

}

return 0;

}

例题——连通块中点的数量

给定一个包含n个点(编号为1~n)的无向图,初始时图中没有边。

现在要进行m个操作,操作共有三种:

“C a b”,在点a和点b之间连一条边,a和b可能相等;

“Q1 a b”,询问点a和点b是否在同一个连通块中,a和b可能相等;

“Q2 a”,询问点a所在连通块中点的数量;

输入格式

第一行输入整数n和m。

接下来m行,每行包含一个操作指令,指令为“C a b”,“Q1 a b”或“Q2 a”中的一种。

输出格式

对于每个询问指令”Q1 a b”,如果a和b在同一个连通块中,则输出“Yes”,否则输出“No”。

对于每个询问指令“Q2 a”,输出一个整数表示点a所在连通块中点的数量

每个结果占一行。

数据范围

1≤n,m≤10^5

输入样例

5 5

C 1 2

Q1 1 2

Q2 1

C 2 5

Q2 5

输出样例

Yes

2

3

代码

#include<iostream>

using namespace std;

const int N = 100010;

int p[N], size1[N];//存储父结点

int n, m;

int find(int x) {//返回x所在集合的编号+路径压缩

if (p[x] != x)

p[x] = find(p[x]);

return p[x];

}

int main() {

scanf("%d%d", &n, &m);

for (int i = 1;i <= n;i++) {

p[i] = i;

size1[i] = 1;

}

while (m--) {

char op[5];

int a, b;

scanf("%s", op);

if (op[0] == 'C') {

scanf("%d%d", &a, &b);

if (find(a) == find(b))

continue;

//特判:如果两个数已经在一个集合,就不用再次合并,不然会使得元素中的元素个数翻倍

size1[find(b)] += size1[find(a)];//b中元素数量为其本身加上a中元素数量

p[find(a)] = find(b);//合并,将a合并到b中

}

else if (op[1] == '1') {

scanf("%d%d", &a, &b);

if (find(a) == find(b))

puts("Yes");

else

puts("No");

}

else {

scanf("%d", &a);

printf("%d\n", size1[find(a)]);

}

}

return 0;

}

http://www.ritt.cn/news/24591.html

相关文章:

  • 有了域名怎么做自己得网站电脑培训中心
  • 做视频网站视频文件都存放在哪网络营销措施有哪些
  • 做网站需要哪些基本功能东莞网站建设哪家公司好
  • asp 网站 源码市场营销培训课程
  • 开发公司装饰装修合同范本简单seo快速排名网站优化
  • 做网站的设计理念自己怎么创建网站
  • phpcms怎么做网站怎么在百度上添加自己的店铺地址
  • 网站怎么做多语言展示关键词排名推广怎么做
  • 网站系统安全保护等级是必须做的搜索关键词排名优化服务
  • 做的网站提示磁盘空间不足今日热点新闻事件摘抄2022
  • 做网站要坚持百度地图导航
  • 常州做企业网站的公司百度seo查询
  • 有了源码怎么搭建网站企业qq怎么申请
  • 有什么发布做投标报价的网站优化推荐
  • 我想找网站帮忙做宣传网络推广工作好吗
  • 政府网站的建设方案开发一个app平台大概需要多少钱?
  • 深圳便宜做网站360推广登录入口官网
  • 石家庄网站制作哪家好百度网站统计
  • 网站设计费用价目表网站搜索
  • 沈阳专业做网站公司百度推广如何计费
  • linux宝塔面板做网站百度检索入口
  • 网站建设成本百度广告电话号码是多少
  • 网站前端做报名框代码百度基木鱼建站
  • b2b和c2c网站营销模式对比研究安徽网站推广
  • 怎么做二级网站武汉网络推广优化
  • 云相册网站怎么做网络做推广公司
  • 江门市做网站电商培训机构靠谱吗
  • 微网站上的一键导航怎么做邯郸seo
  • 设计官网首页谷歌seo公司
  • 武汉快速推广建站公司免费使用seo软件