96SEO 2026-02-19 10:13 15
虽然说是借用了jiangly鸽鸽的板子#xff0c;但是自己也小做…一、前言

因为要开始准备年底的校赛和明年年初的ACM、蓝桥杯、天梯赛于是开始按专题梳理一下对应的知识点先从简单入门又值得记录的内容开始并查集首当其冲。
虽然说是借用了jiangly鸽鸽的板子但是自己也小做修改了部分命名啥的大体内容并没有修改jiangly鸽鸽yyds
_fa,_size;DisjointSet(){}DisjointSet(int
{_fa.resize(n);std::iota(_fa.begin(),_fa.end(),0);_size.assign(n,1);}int
set英文直译过来是不相交的集合。
我们中文取名成并查集是因为这类集合主要具有两个操作并和查并即合并两个集合查即查询集合的某些信息。
如果有学习过树的知识那么理解并查集就比较轻松了。
“并”操作类似于将森林两棵树转化为一棵树我们只需要让其中一个并查集的根节点的父亲结点指向另外一个并查集的根节点即可。
当然选择的时候我们倾向于让深度小的树的根节点指向深度大的树的根节点。
不过后续用上路径压缩后谁指向谁基本没有什么太大的影响。
实际写代码中我们主要的操作就是对一个并查集的根节点进行修改
在没有进行任何合并前一个并查集的根节点应该为它自身切记写代码的时候不要忘记并查集的初始化当然如果用我的模板的话就不会忘记初始化构造函数已经写好初始化了
正常来说并查集合并的时间复杂度为O(1)而查询的最坏时间复杂度为O(n)常见的最坏情况就是只有左子树或者只有右子树的一棵树的查询。
而如果我们在查询时顺带将查询路径上的结点的父节点属性顺带修改为真正的根节点那么综合下来时间复杂度将会被均摊成O(logn)这是一个非常优秀的优化。
这道题是很典型的用并查集做的题目先对并查集进行初始化我们直接把有关系的两人进行合并如果已经处于同一个并查集中则不做操作。
后续题目需要我们查询的是并查集的数量以及并查集中最大的节点数量
前面都是并查集模板注意构造并查集的时候至少把节点数1因为用于实现的vetcor下标从0开始大部分题目的下标是从1开始的最后查询的时候利用set进行排序输出即可
_fa,_size;DisjointSet(){}DisjointSet(int
{_fa.resize(n);std::iota(_fa.begin(),_fa.end(),0);_size.assign(n,1);}int
{std::cin.tie(nullptr)-sync_with_stdio(false);int
mem2;disjointSet.merge(mem1,mem2);}std::setpii
disjointSet.find(i);st.insert(std::make_pair(disjointSet._size[t],t));}std::cout
这个题由于enemy的存在需要多维护一个ene[]数组ene[]数组初始化为0如果遇到p等于0的时候分别判断x和y的ene是否为0如果为0则代表他们当前没有enemy则把ene值设置成对方即x和y分别属于两个并查集中如果当前存在ene那么就把自己合并到他们enemy的并查集中因为敌人的敌人是朋友。
至于p等于1的情况当做正常并查集的合并来做。
最后输出并查集的数量计算父节点等于自身的节点数量即可
_fa,_size;DisjointSet(){}DisjointSet(int
{_fa.resize(n);std::iota(_fa.begin(),_fa.end(),0);_size.assign(n,1);}int
{std::cin.tie(nullptr)-sync_with_stdio(false);int
{disjointSet.merge(y,ene[x]);}else
{disjointSet.merge(x,ene[y]);}else
{//frienddisjointSet.merge(x,y);}}int
题目有点反直觉我一开始想着从1到k依次进行判断断开某个关系后可以使得他们中最大的一个危险程度小于等于n/2然后后来发现写起来很困难。
正难则反因此我们考虑从n开始循环跑到1结束每次循环让这个循环变量i这个节点和它有关系并且大于k的j节点进行合并然后看看是否有危险程度大于n/2的并查集即可。
_fa,_size;DisjointSet(){}DisjointSet(int
{_fa.resize(n);std::iota(_fa.begin(),_fa.end(),0);_size.assign(n,1);}int
{std::cin.tie(nullptr)-sync_with_stdio(false);int
edges(n1,std::vectorint());DisjointSet
t;edges[i1].emplace_back(t);}}for(int
{disjointSet.merge(k,edge);}}if(disjointSet._size[disjointSet.find(k)]n/2)
并查集01背包中间对数据的存储搞得我很头疼用了一堆vector先把c[]和d[]数组存起来做了并查集的合并后再算一个并查集c[]的总和sumc[]以及d[]的总和sumd[]然后把计算好的总和放进real_c[]和real_d[]数组中再使用一个dp[]数组做一遍01背包最后的dp[w]输出即可
_fa,_size;DisjointSet(){}DisjointSet(int
{_fa.resize(n);std::iota(_fa.begin(),_fa.end(),0);_size.assign(n,1);}int
{std::cin.tie(nullptr)-sync_with_stdio(false);int
tmpd;c.emplace_back(tmpc);d.emplace_back(tmpd);}DisjointSet
y;disjointSet.merge(x,y);}std::vectorint
{real_c.emplace_back(sumc[i]);real_d.emplace_back(sumd[i]);}}std::vectorint
std::max(dp[j],dp[j-real_c[i]]real_d[i]);}}std::cout
剩下的题目及并查集的进一步运用求最小生成树的Kruskal算法见后续的2
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback