2019-01-30

最小生成树基本算法

定义

给定一个边带权的无向图G=(V,E),n=|V|,m=|E|,由V中全部n个定点和E中n-1条边构成的无向连通子图被称为G的一颗生成树。

边的权值之和最小的生成树被称为无向图G的最小生成树。(Minimun Spanning Tree,MST).

定理

任意一颗最小生成树一定包含无向图中权值最小的边

证明:

假设最小的边z不在MST上,将其加入树中,可构成一个环,并且环上所有边权都比z大,因此用z代表任意一条边,所得的生成树都一定会比原来更小。假设不成立。

Kruskal:
桉边权排序,然后依次扫描每个边(x,y,z),若x,y属于同一个集合,则忽略这条边,否则合并x,y所在的集合,将z累加到答案中。---O(mlogm)

代码:

#include <cstdio>
#include <algorithm>
using namespace std; struct rec{
int x,y,z;
}e[200010]; int cmp(rec a,rec b){
return a.z<b.z;
}
int fa[5010],n,m,ans=0; int get(int x){
if(x==fa[x]) return x;
return fa[x]=get(fa[x]);
} int main(){
scanf("%d%d",&n,&m);
for(int i=1 ; i<=m ; i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
sort(e+1,e+1+m,cmp);
for(int i=1 ; i<=n ; i++) fa[i]=i; for(int i=1 ; i<=m ; i++){
int x=get(e[i].x);
int y=get(e[i].y);
if(x==y) continue;
fa[x]=y;
ans+=e[i].z;
}
printf("%d\n",ans);
return 0;
}

  

Prim:

任一时刻,设已经确定属于最小生成树的节点集合为T,剩余点集合为S,找到minx€S,y€T 即两个端点分别属于S和T的权值最小的边,然后把点x从集合S中删除,加入集合T,并把该边边权累加到答案中。

具体来说,就是一个维护数组d[x]:  当x未被选中时,表示x与S中的节点间权值最小的边的权值。 若x已被选中,表示 x被选中加入已选集合时选中的最小边的权值。

遍历1~n-1每个点,每次选出T中d[]最小的点加入集合S,然后更新T中其它点的d值---O(n^2),

代码:

#include <cstdio>
#include <algorithm>
using namespace std; struct rec{
int x,y,z;
}e[200010]; int cmp(rec a,rec b){
return a.z<b.z;
}
int fa[5010],n,m,ans=0; int get(int x){
if(x==fa[x]) return x;
return fa[x]=get(fa[x]);
} int main(){
scanf("%d%d",&n,&m);
for(int i=1 ; i<=m ; i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
sort(e+1,e+1+m,cmp);
for(int i=1 ; i<=n ; i++) fa[i]=i; for(int i=1 ; i<=m ; i++){
int x=get(e[i].x);
int y=get(e[i].y);
if(x==y) continue;
fa[x]=y;
ans+=e[i].z;
}
printf("%d\n",ans);
return 0;
}

  

Prim优先队列优化---O(mlogn)

const int N=3010;
int a[N][N],d[N],n,m,ans;
bool v[N]; void prim()
{
memset(d,0x3f,sizeof(d));
memset(v,0,sizeof(v));
d[1]=0;
for(int i=1 ; i<n ; i++)
{
int x(0);
for(int j=1 ; j<=n ; j++)
if(!v[j]&&d[j]<d[x]) x=j;
v[x]=1;
for(int y=1 ; y<=n ; y++)
if(!v[y])
d[y]=min(d[y],d[x]+a[x][y]);
}
} int main()
{
prim();
for(int i=2 ; i<=n ; i++) ans+=d[i];
}

  

P3366 (模板)最小生成树的更多相关文章

  1. [洛谷P3366] [模板] 最小生成树

    存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...

  2. 【洛谷 p3366】模板-最小生成树(图论)

    题目:给出一个无向图,求出最小生成树,如果该图不连通,则输出orz. 解法:Kruskal求MST. 1 #include<cstdio> 2 #include<cstdlib> ...

  3. luoguP3366 [模板] 最小生成树

    题目链接:https://www.luogu.org/problemnew/show/P3366 思路: 求最小生成树的模板题,求MST有两种算法——Prim.Kruskal. 两者区别:Prim在稠 ...

  4. 模板<最小生成树>

    转载 最小生成树浅谈 这里介绍最小生成树的两种方法:Prim和Kruskal. 两者区别:Prim在稠密图中比Kruskal优,在稀疏图中比Kruskal劣.Prim是以更新过的节点的连边找最小值,K ...

  5. 模板——最小生成树prim算法&&向前星理解

    通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...

  6. 模板——最小生成树kruskal算法+并查集数据结构

    并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...

  7. P3366 【模板】最小生成树

    原题链接 https://www.luogu.org/problemnew/show/P3366 一道最小生成树的模板题...... 昨天刚学最小生成树,wz大佬讲的一塌糊涂井然有序,所以我们今天做起 ...

  8. 洛谷P3366 【模板】最小生成树

    P3366 [模板]最小生成树 319通过 791提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 里面没有要输出orz的测试点 如果你用Prim写了半天都是W- 题目 ...

  9. P3366 【模板】最小生成树(boruvka/sollin)

    P3366 [模板]最小生成树 boruvka/sollin 复杂度$O(mlogn)$ 简要说明一下过程 引入一个数组$link[i]$表示连通块$i$下一步可更新的最短的边的编号 1.每次枚举所有 ...

随机推荐

  1. OpenNebula 4.0 Beta 新特性介绍

    http://blog.chinaunix.net/uid-20940095-id-3561376.html 2013年3月26号,OpenNebula社区发布了OpenNebula 4.0 Beta ...

  2. EntityFramework - Code First - 数据迁移

    需求 在更新模型之后同步更新数据库里的表,并不丢失原有数据 使用默认值填充新增加的字段 EntityFramework迁移命令 Enable-Migrations 启用迁移 Add-Migration ...

  3. ECS 游戏架构 实现

    转载自:http://blog.csdn.net/i_dovelemon/article/details/27230719 实现 组件-实体-系统 - 博客频道   这篇文章是在我前面文章,理解组件- ...

  4. python中执行命令的3种方法小结-乾颐堂

    目前我使用到的python中执行cmd的方式有三种: 1. 使用os.system("cmd") 特点是执行的时候程序会打出cmd在linux上执行的信息. import os o ...

  5. SliceBox

    SliceBox相当于一个轮播图插件,只不过是3D的. 先来查看它能实现的效果: 官网:http://tympanus.net/codrops/2011/09/05/slicebox-3d-image ...

  6. nhibernate 3.x新特性

    http://www.360doc.com/content/14/0226/17/9316347_355904008.shtml

  7. DapperExtensions 使用教程

    最近搭建一个框架,使用dapper来做数据库访问,数据是sql server2012,支持多个数据库.事务.orm.ado.net原生操作方式,非常方便. 使用dapper的原因网上有很多文章说明,这 ...

  8. java中Integer常量池

    我们先看一个关于Integer的例子 public static void main(String[] args) { // TeODO Auto-generated method stu Integ ...

  9. [转]Linux Swap交换分区、交换文件

    free -m 在日常应用中,通过上述命令看到交换空间的使用情况为0,那么你就不需要很大的虚拟内存,甚至可以完全不需要另辟硬盘空间作为虚拟内存.那么,万一有一天你需要了呢,难道要重装系统?大可不必,在 ...

  10. Animator 设置动画效果

    1. 调节预设对象大小适中 2. 设置骨骼,修改关节 3. 拖入预设动作效果对象中 4. 将预设对象拉入场景中,并新建AnimatorController 5. 新建动作或BlendTree,设置参数 ...