尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

qoj4239 MST

qoj4239 MST
📅 发布时间:2026/6/19 8:59:16

题意

给出 \(n\) 个整数 \(a_i\)。有一个 \(n\) 个点的无向完全图,定义 \(x,y\pod {x<y}\) 的边权为 \(a_y-a_x\),问这个图的最小生成树。

思路

完全图最小生成树,考虑 Boruvka 最小生成树算法。

具体的说,初始状态为 \(n\) 个单独的点,因此有 \(n\) 个连通块。

每次对每个连通块找到连接到另一个连通块的最小边权,全部找完后进行连接,若要连接的两个原连通块不在同一连通块中则连接。

随后递归进行以上操作,即可求出最小生成树。

由于每次规模缩小一半,所以复杂度是 \(O(n\log n)\) 的,前提是能快速找到连接另一连通块的最小边权。

对于 \(a_i\),显然在它的左边的最大 \(a_i\) 和在它右边的最小 \(a_i\) 可能成为连接它的最小边权。

于是我们对 \(i\) 维护在 \(i\) 左边的最大 \(a_i\) 和右边的最小 \(a_i\),且不在同一连通块中。

可以用一个 set 存下每个连通块的最大最小值,若要求的最大最小值为该连通块,则后移一位即可。

代码

💩💩💩💩💩💩💩

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
int T,n,a[300005],f[300005],f2[300005],mx1[300005],mn1[300005],mnm[300005],mni[300005];
set<pair<int,int>> imx,imn;//最大值,连通块
int lmx[300005],lmn[300005];
int find(int x){if(f[x]!=x) f[x]=find(f[x]);return f[x];
}
int find2(int x){if(f2[x]!=x) f2[x]=find2(f2[x]);return f2[x];
}
int boruvka(){//1 8for(int i=1;i<=n;i++)f[i]=i,f2[i]=i;int cnt=n,res=0;while(cnt!=1){imx.clear();for(int i=1;i<=n;i++)mnm[i]=inf,mni[i]=0,lmx[i]=0,mx1[i]=0,imx.insert({-inf,find(i)});a[0]=-inf;for(int i=1;i<=n;i++){mx1[i]=lmx[prev(imx.end())->second];if(find(mx1[i])==find(i)){if(imx.size()>1)mx1[i]=lmx[prev(prev(imx.end()))->second];elsemx1[i]=0;}imx.erase({a[lmx[find(i)]],find(i)});if(a[i]>a[lmx[find(i)]])lmx[find(i)]=i;imx.insert({a[lmx[find(i)]],find(i)});}imn.clear();for(int i=1;i<=n;i++)lmn[i]=0,mn1[i]=0,imn.insert({inf,find(i)});a[0]=inf;for(int i=n;i>=1;i--){mn1[i]=lmn[imn.begin()->second];if(find(mn1[i])==find(i)){if(imn.size()>1)mn1[i]=lmn[next(imn.begin())->second];elsemn1[i]=inf;}imn.erase({a[lmn[find(i)]],find(i)});if(a[i]<a[lmn[find(i)]])lmn[find(i)]=i;imn.insert({a[lmn[find(i)]],find(i)});}for(int vl,id,i=1;i<=n;i++){if(mx1[i]==0) id=mn1[i];else if(mn1[i]==0) id=mx1[i];else if(a[i]-a[mx1[i]]<=a[mn1[i]]-a[i]) id=mx1[i];else id=mn1[i];vl=(id<i?a[i]-a[id]:a[id]-a[i]);if(vl<mnm[find(i)]){mnm[find(i)]=vl;mni[find(i)]=id;}}for(int i=1;i<=n;i++)f2[i]=f[i];for(int i=1;i<=n;i++){if(mni[find(i)]==0) continue;int xx=find2(i),yy=find2(mni[find(i)]);if(xx!=yy){res+=mnm[find(i)];f2[xx]=yy;cnt--;}mni[find(i)]=0;}for(int i=1;i<=n;i++)f[i]=f2[i];}return res;
}
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];cout<<boruvka()<<endl;}return 0; 
}

相关新闻

  • 第一篇博客
  • springboot的启动流程
  • 「微积分 A1」基础知识(连载中)

最新新闻

  • 2026银川2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 字节跳动拟购5万颗AI芯片,国产GPU竞争聚焦生态、成本与产能
  • 基于深度学习的糖尿病视网膜病变自动检测系统构建实战
  • Obsidian MCL布局:模块化CSS让你的笔记排版焕然一新
  • 逆向工程实战:从加密音乐文件到通用音频格式的转换原理
  • NGA论坛优化摸鱼体验:免费开源脚本让你的论坛浏览效率提升300%

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号