今天做了一道题,根本没想到最小生成树,稀里糊涂的浪费了很多时间,复习一下

转载自https://www.cnblogs.com/zhangming-blog/p/5414514.html

Prim算法

1.概览

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

2.算法简单描述

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;

2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;

3).重复下列操作,直到Vnew = V:

a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。

示例图演示:

下面对算法的图例描述:

图例 说明 不可选 可选 已选(Vnew

此为原始的加权连通图。每条边一侧的数字代表其权值。 - - -

顶点D被任意选为起始点。顶点ABEF通过单条边与D相连。A是距离D最近的顶点,因此将A及对应边AD以高亮表示。 C, G A, B, E, F D

下一个顶点为距离DA最近的顶点。BD为9,距A为7,E为15,F为6。因此,FDA最近,因此将顶点F与相应边DF以高亮表示。 C, G B, E, F A, D
算法继续重复上面的步骤。距离A为7的顶点B被高亮表示。 C B, E, G A, D, F

在当前情况下,可以在CEG间进行选择。CB为8,EB为7,GF为11。E最近,因此将顶点E与相应边BE高亮表示。 C, E, G A, D, F, B

这里,可供选择的顶点只有CGCE为5,GE为9,故选取C,并与边EC一同高亮表示。 C, G A, D, F, B, E

顶点G是唯一剩下的顶点,它距F为11,距E为9,E最近,故高亮表示G及相应边EG G A, D, F, B, E, C

现在,所有顶点均已被选取,图中绿色部分即为连通图的最小生成树。在此例中,最小生成树的权值之和为39。 A, D, F, B, E, C, G

3.简单证明prim算法

反证法:假设prim生成的不是最小生成树

1).设prim生成的树为G0

2).假设存在Gmin使得cost(Gmin)<cost(G0)   则在Gmin中存在<u,v>不属于G0

3).将<u,v>加入G0中可得一个环,且<u,v>不是该环的最长边(这是因为<u,v>∈Gmin)

4).这与prim每次生成最短边矛盾

5).故假设不成立,命题得证.

再贴一个模板,转载自https://blog.csdn.net/zwj1452267376/article/details/47603933

最小生成树就是:

在所有数据满足是一棵树的情况下一条将所有节点都连接起来且长度最短的一条路(因为任意两个节点之间有权值

(相连的两点之间权值为一个具体的数,不相连的两个点之间权值为无穷大))

下面介绍通用的求最小生成树的两种算法:

ps:这里用的两种算法都是用邻接矩阵实现适合点稠密型数据或者数据较小的情况:

 <span style="font-size:12px;">/*
* 数组tree[]用来记录最小生成树的节点
* 数组lowdis[]记录从起点到其余所有点的距离并不断更新
* 数组map[][]记录所有数据两点之间的距离
* point是所有节点的数目,begin是起点
* mindis是最小生成树的长度
*/
void prime()
{
int i,j,min,mindis=,next;
memset(tree,,sizeof(tree));
for(i=;i<=point;i++)
{
lowdis[i]=map[begin][i];//用lowdis[]数组记录下从起点到剩下所有点的距离
}
tree[begin]=;//标记起点(即最小生成树中的点)
for(i=;i<point;i++)
{
min=INF;
for(j=;j<=point;j++)
{
if(!tree[j]&&min>lowdis[j])
{
min=lowdis[j];//求出从当前起点到其余所有点的距离中最短的
next=j;
}
}
mindis+=min;//记录下整条最小树的长度
tree[next]=;
for(j=;j<=point;j++)
{
if(!tree[j]&&lowdis[j]>map[next][j])
lowdis[j]=map[next][j];//更新lowdis[]数组
}
}
printf("%d\n",mindis);
}</span>

ACM__最小生成树之prime的更多相关文章

  1. 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)

    一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...

  2. 最小生成树---Kruskal/Prime算法

    1.Kruskal算法 图的存贮采用边集数组或邻接矩阵,权值相等的边在数组中排列次序可任意,边较多的不很实用,浪费时间,适合稀疏图.      方法:将图中边按其权值由小到大的次序顺序选取,若选边后不 ...

  3. 最小生成树之Prime法

    关于最小生成树的概念,在前一篇文章中已经讲到,就不在赘述了.下面介绍Prime算法:         其基本思想为:从一个顶点出发,选择由该顶点出发的最小权值边,并将该边的另一个顶点包含进来,然后找出 ...

  4. 【算法导论】最小生成树之Prime法

    关于最小生成树的概念,在前一篇文章中已经讲到,就不在赘述了.下面介绍Prime算法:         其基本思想为:从一个顶点出发,选择由该顶点出发的最小权值边,并将该边的另一个顶点包含进来,然后找出 ...

  5. 最小生成树之prime算法

    public class Prime { public static void main(String[] args) { //路径矩阵 int arcs[][] = {{-1,6,1,5,-1,-1 ...

  6. poj 1258 Agri-Net【最小生成树(prime算法)】

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44827   Accepted: 18351 Descri ...

  7. 最小生成树(Prime算法)

    最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城 ...

  8. hdu 1233(还是畅通project)(prime算法,克鲁斯卡尔算法)(并查集,最小生成树)

    还是畅通project Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  9. 51nod1459(带权值的dijkstra)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1459 题意:中文题诶- 思路:带权值的最短路,这道题数据也没 ...

随机推荐

  1. folly无锁队列,尝试添加新的函数

    1. folly是facebook开源的关于无锁队列的库,实现过程很精妙.folly向队列中添加节点过程,符合标准库中的队列的设计,而取出节点的过程,则会造成多个线程的分配不均.我曾经试着提供一次 取 ...

  2. Kubernetes报错Failed to get system container stats for "/system.slice/kubelet.service"

    tail -f /var/log/message Nov 14 07:12:51 image kubelet: E1114 07:12:51.627782    3007 summary.go:92] ...

  3. library之目录

    组件之fragment: Android viewpager结合fragment的相关优化: 组件之webview: WebView的使用及实战(cookie同步和cookie清除); Android ...

  4. python面向对象 : 继承

    一. 初识继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. 当我们在定义多个类的时候,发现要用到相同的方法或变量,如 ...

  5. CRM 2016 一个IFrame_A 刷新另一个 IFrame_B

    思路是 : 1 创建一个字段“new_xxx”. 2 注册字段 OnChange 事件. 3 OnChange 事件 刷新 IFrame_B子页面. CRM父页面JS: /// <summary ...

  6. 2018北美部分CS项目学费

    yearly cost from official website USC 城里 24credit about 49k + cost of room&food BU 城里 NEU 65k 城里 ...

  7. (转)OpenSystemArchitect - 根据数据库表逆向生成数据模型

    原文地址:http://www.cnblogs.com/zhaojin/archive/2011/04/14/2016478.html OpenSystemArchitect - 根据数据库表逆向生成 ...

  8. 在django中使用django_debug_toolbar进行日志记录

    一.概述 django_debug_toolbar 是django的第三方工具包,给django扩展了调试功能. 包括查看执行的sql语句,db查询次数,request,headers,调试概览等.  ...

  9. linux:ubuntu安装mysql(二)--推荐

    1)下载mysql安装包mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz,下载地址:https://dev.mysql.com/downloads/mysql/ 2 ...

  10. CheckedListBox  数据绑定

    CheckedListBox  数据绑定方式有多总,常用的绑定方式总结如下: 1.  Items.Add 通过 Itemes.Add 方法来向 CheckedListBox  中添加项 2. Data ...