首页 > 其他分享 >最小生成树

最小生成树

时间:2023-10-07 09:56:23浏览次数:23  
标签:5002 Prim log int 最小 生成 dis

忘了具体什么时候写的,应该是 2023.8 初

这算是个算法复习,因为我太菜了以前学的都不会了。

最小生成树

Prim

本质就是一个点去更新它的所有边连接的点,因为最小生成树的本质是形成一个 \(n-1\) 条边的联通图,所以我们需要达成两个条件:

  • 所有点都联通
  • 每个点选的边尽可能小

所以我们就可以考虑贪心,我们假设 \(1\) 号节点是开始位置,最终所有的点都要和它联通,我们令 \(dis_i\) 表示 \(i\) 点被联通所需要的最小代价,然后从 \(dis\) 最小的 \(i\) 开始更新(一开始是从 \(1\) 开始,\(dis_1=0\)),然后把每个 \(dis\) 更新并且加到优先队列里(优先队列维护最小 \(dis\))。

是不是很像 \(dijkstra\),其实用到的贪心思路都差不多,就是用每次用当前得到的最优解去更新其他点的答案,最后得到全局的答案。

所以我们就得到了一个跟 \(Dijkstra\) 长得非常像并且复杂度比较稳定在(\(O(n\log n)\))的代码:

\(Code\)

//Prim O(n log n)
typedef pair<int,int> PII;
int n,m,dis[5002],ans,cnt;
bool vis[5002];
vector<PII>f[5002];
priority_queue<PII>Q;
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),w=read();
        f[u].push_back({v,w});
        f[v].push_back({u,w});
    }
    memset(dis,0x3f,sizeof(dis));
    Q.push({(dis[1]=0),1});
    while(!Q.empty()&&cnt<n){
        int x=Q.top().second;Q.pop();
        if(vis[x])continue;
        vis[x]=1;
        cnt++,ans+=dis[x];
        for(PII PI:f[x]){
            int y=PI.first,w=PI.second;
            if(dis[y]>w)dis[y]=w,Q.push({-w,y});
        }
    }    
    if(cnt!=n)puts("orz");
    else printf("%d",ans);
}

Kruskal

本质也是和 \(Prim\) 一样,找尽可能最小边,我们发现最小的边如果可以连接两个不同的连通块,那么一定会被选。假设我们不选,此时我们用另外一条比较大的边连接这两个连通块,答案肯定不是最优的。

当然加边之前还得确认两个点不在一个连通块内,用并查集维护即可。

极限最优复杂度 \(O(m\log m\alpha(n))\)。(O(\(\alpha(n)\)) 是并查集复杂度)

按理来说应该不会比我的 \(Prim\) 快,但是可能是有小优化,居然跑飞快。

\(Code\)

//Kruskal O(m\log m \log n)
struct edge{
    int u,v,w;
    inline bool operator <(const edge &o)const{
        return w>o.w;
    }
};
int n,m,fa[5002],ans,cnt=1;
priority_queue<edge>Q;
inline int find(int x){return (x==fa[x]?x:(fa[x]=find(fa[x])));}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),w=read();
        Q.push({u,v,w});
    }
    while(!Q.empty()&&cnt<n){
        int u=Q.top().u,v=Q.top().v,w=Q.top().w;
        Q.pop();
        if(find(u)==find(v))continue;
        cnt++,ans+=w;
        fa[find(u)]=find(v);
    }
    if(cnt!=n)puts("orz");
    else printf("%d",ans);
}

标签:5002,Prim,log,int,最小,生成,dis
From: https://www.cnblogs.com/NBest/p/17745588.html

相关文章

  • Java生成6位随机数(数字和拼音)Demo
    publicstaticvoidmain(String[]args){//length=6生成的位数intlength=6;StringBuffersb=newStringBuffer();StringALLCHAR="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";Randomrandom=newRandom();f......
  • springboot中的代码生成器
    springboot可以集成MyBatis-Plus代码生成器,如何想要快速开发或者考试可以试用一下。我参看下面这篇博客弄的:Mybatis-Plus自动生成代码,自定义Controller_mybatisplus生成controller-CSDN博客有些好用 ......
  • Redis学习之分布式全局id生成
    介绍为什么需要分布式全局ID生成器?对于订单这种数据,数据库自增的规律性太明显,会暴露一些信息(比如根据昨日和今日的订单号差值看出销量)数据量过大时,不同表的id分别自增,容易出现id冲突分布式全局ID生成应满足的特点:唯一:整个系统每个id都是唯一的递增......
  • 为研究不同宽度,厚度,重量,车间温度,冷却方式下,物料温度随时间呈指数衰减的模型函数,
    为研究不同宽度,厚度,重量,车间温度,冷却方式下,物料温度随时间呈指数衰减的模型函数,请使用python按照下面的表格形式,生成模拟数据,数据预处理,选择模型,划分数据集,训练模型,调整超参数,预测和评估,并绘图谢谢您的反馈。我可以尝试改进模拟生成的df数据,以让它更加真实。......
  • 不同宽度,厚度,重量,车间温度,冷却方式下,物料温度随时间衰减,请使用python机器学习,
    生成模拟数据、数据预处理、选择模型、划分数据集、训练模型、调整超参数、预测和评估以及绘图是一个相对复杂的流程。下面是一个示例流程,涵盖了这些步骤:importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltfromsklearn.model_selectionimporttrain_test_......
  • 不同宽度,厚度,重量,车间温度,冷却方式下,物料温度随时间呈指数衰减,,请使用python机
    生成模拟数据、数据预处理、选择模型、划分数据集、训练模型、调整超参数、预测和评估以及绘制图表是一个完整的机器学习项目流程。下面是一个用Python完成这些步骤的基本示例。请注意,这只是一个简单的示例,实际项目中可能需要更复杂的数据和模型选择。首先,确保你已经安装了必要的Py......
  • 力扣-1646-获取生成数组中的最大值
    给你一个整数n。按下述规则生成一个长度为n+1的数组nums:nums[0]=0nums[1]=1当2<=2*i<=n时,nums[2*i]=nums[i]当2<=2*i+1<=n时,nums[2*i+1]=nums[i]+nums[i+1]返回生成数组nums中的最大值。 示例1:输入:n=7输出:3解释:根据规则:......
  • Ansible Lightspeed Ai自动化生成yml语句
    写作时间:2023/10/4操作环境:VscodeLinuxAnsibleLightspeed是什么AnsibleLightspeed是AI可以自动生成AnsiblePlaybook任务,红帽表示,这一新功能使Ansible新手用户更容易实现任务自动化,从而减轻了自动化专业人员创建低级任务的负担。用户可以使用英文命令生成AnsiblePlaybook......
  • 使用Aspose.Cell控件实现Excel高难度报表的生成(二)
    继续在上篇《使用Aspose.Cell控件实现Excel高难度报表的生成(一)》随笔基础上,研究探讨基于模板的Aspose.cell报表实现,其中提到了下面两种报表的界面,如下所示: 或者这样的报表格式  首先来分析第一种报表,这个其实还是比较固定的二维表,我们只要绑定相关的信息即可,设计模板如下......
  • 最小生成树
    一个连通且无回路的无向图称为树。在树中度数为1的节点为叶,度数大于1的节点称为分枝点或内节点。给定图T,以下关于树的定义是等价的。(1)无回路的连通图。(2)无回路且e=v-1,其中e为边数,v为节点数(3)连通且e=v-1。(4)无回路且增加一条新边,得到一个且仅一个回路(5)连通且删去任何一个......