Prim算法:    
以前一直不是很明白,Prim算法,今天就来终结一下。
Prim算法采用与Dijkstra、Bellman-Ford算法一样的“蓝白点”思想:白点代表已经进入最小生成树的点,蓝点代表未进入最小生成树的点。
算法描述:
以1为起点生成最小生成树,min[v]表示蓝点v与白点相连的最小边权。
MST表示最小生成树的权值之和。
a)初始化:min[v]= ∞(v≠1); min[1]=0;MST=0;
b)for (i = 1; i<= n; i++)
1.寻找min[u]最小的蓝点u。
2.将u标记为白点
3.MST+=min[u]
4.for 与白点u相连的所有蓝点v 
                 if (w[u][v]<min[v])
                      min[v]=w[u][v];
c)算法结束: MST即为最小生成树的权值之和
 
算法分析&思想讲解:
    Prim算法每次循环都将一个蓝点u变为白点,并且此蓝点u与白点相连的最小边权min[u]还是当前所有蓝点中最小的。这样相当于向生成树中添加了n-1次最小的边,最后得到的一定是最小生成树。

例题:(cojs)602. 新的开始

★★   输入文件:newstart.in   输出文件:newstart.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】

发展采矿业当然首先得有矿井,  小  FF  花了上次探险获得的千分之一的财富请人在岛

上挖了 n 口矿井,  但他似乎忘记考虑的矿井供电问题……

为了保证电力的供应,  小 FF 想到了两种办法:

1、  在这一口矿井上建立一个发电站,  费用为  v(发电站的输出功率可以供给任

意多个矿井)。

2、  将这口矿井与另外的已经有电力供应的矿井之间建立电网,  费用为 p。

小 FF 希望身为”NewBe_One"  计划首席工程师的你帮他想出一个保证所有矿井电力供

应的最小花费。

【输入格式】

第一行一个整数 n,  表示矿井总数。

第 2~n+1 行,每行一个整数,  第 i 个数 v[i]表示在第 i 口矿井上建立发电站的费用。

接下来为一个 n*n 的矩阵 P,  其中 p[ i , j ]表示在第 i 口矿井和第 j 口矿井之间建立

电网的费用(数据保证有 p[ i, j ] = p[ j, i ],  且  p[ i, i ]=0)。

【输出格式】

仅一个整数,  表示让所有矿井获得充足电能的最小花费。

【输入样例】

4

5

4

4

3

0 2 2 2

2 0 3 3

2 3 0 4

2 3 4 0

【输出样例】

9

输出样例说明:

小 FF 可以选择在4号矿井建立发电站然后把所有矿井都与其建立电网,总花费是

3+2+2+2 = 9。

【数据范围】

对于30%的数据:      1<=n<=50;

对于100%的数据:    1<=n<=300;      0<=v[i], p[i,j] <=10^5.

/*先加点,再跑最小生成树*/
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#define INF (1<<31)-1
#define N 621
int n;
struct Edge{
int v,w,last;
};
Edge edge[N*N];
int t=;
int head[N],miu[N];
bool flag[N];
long long int mst=;
void input()
{
scanf("%d",&n);
int a;
for(int i=;i<=n;++i)
{
scanf("%d",&a);
++t;
edge[t].v=i;
edge[t].w=a;
edge[t].last=head[n+];
head[n+]=t;
++t;
edge[t].v=n+;
edge[t].w=a;
edge[t].last=head[i];
head[i]=t;
}
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
{
scanf("%d",&a);
++t;
edge[t].v=j;
edge[t].w=a;
edge[t].last=head[i];
head[i]=t;
}
n+=;
}
void Prim()
{
mst=;
memset(miu,,sizeof(miu));
miu[n]=;/*从第n个点开始建树*/
memset(flag,false,sizeof(flag));
int p,maxx=INF;
for(int i=;i<=n;++i)
{
maxx=INF;
for(int j=;j<=n;++j)
{/*!flag[j],找出miu最小的蓝点p*/
if(!flag[j]&&miu[j]<maxx)
{
maxx=miu[j];
p=j;
}
}
flag[p]=true;/*标记*/
mst+=miu[p];/*把p加入树内*/
for(int l=head[p];l;l=edge[l].last)
{
int vi=edge[l].v;
if(!flag[vi]&&edge[l].w<miu[vi])
miu[vi]=edge[l].w;/*miu储存着蓝点vi到白点的最小距离*/
}
}
}
int main()
{
freopen("newstart.in","r",stdin);
freopen("newstart.out","w",stdout);
input();
Prim();
cout<<mst<<endl;
fclose(stdin);
fclose(stdout);
return ;
}

Prim算法

 

最小生成树之Prim算法--蓝白点思想的更多相关文章

  1. 数据结构(C实现)------- 最小生成树之Prim算法

    [本文是自己学习所做笔记.欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020] 算法描写叙述 假设连通图是一个网,则称该网中全部生成树中权值总和最小的生成树 ...

  2. 数据结构与算法--最小生成树之Prim算法

    数据结构与算法--最小生成树之Prim算法 加权图是一种为每条边关联一个权值或称为成本的图模型.所谓生成树,是某图的一棵含有全部n个顶点的无环连通子图,它有n - 1条边.最小生成树(MST)是加权图 ...

  3. 24最小生成树之Prim算法

    最小生成树的Prim算法 思想:采用子树延伸法 将顶点分成两类: 生长点——已经在生成树上的顶点 非生长点——未长到生成树上的顶点 使用待选边表: 每个非生长点在待选边表中有一条待选边,一端连着非生长 ...

  4. 最小生成树的Prim算法

       构造最小生成树的Prim算法    假设G=(V,E)为一连通网,其中V为网中所有顶点的集合,E为网中所有带权边的集合.设置两个新的集合U和T,其中集合U用于存放G的最小生成树的顶点,集合T用于 ...

  5. hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)

    还是畅通工程                                                                            Time Limit: 4000/2 ...

  6. 算法学习记录-图——最小生成树之prim算法

    一个连通图的生成树是一个极小的连通子图,它包含图中全部的顶点(n个顶点),但只有n-1条边. 最小生成树:构造连通网的最小代价(最小权值)生成树. prim算法在严蔚敏树上有解释,但是都是数学语言,很 ...

  7. Hihocoder 之 #1097 : 最小生成树一·Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)

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

  8. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  9. 最小生成树一·Prim算法

    描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...

随机推荐

  1. Java——关于static关键字的那些事总结

    前言: 先说说今天为啥要谈这个东西,虽然学Java已经有两年了,但是今天,本着温故而知新的态度,仔细的第三次翻看了<Head Firt Java>这本书,虽然这本书介绍的很多东西都特别基础 ...

  2. ImportError: libQtTest.so.4: cannot open shared

    错误: import cv2 File , in <module> from .cv2 import * ImportError: libQtTest.so.: cannot open s ...

  3. skb管理函数之skb_clone、pskb_copy、skb_copy

    skb_clone--只复制skb描述符本身,如果只修改skb描述符则使用该函数克隆: pskb_copy--复制skb描述符+线性数据区域(包括skb_shared_info),如果需要修改描述符以 ...

  4. centos 安装flash

    linux系统中安装flash插件 linux中安装flashplayer插件的简单方法: 1.下载其中最新版本的播放器,下载地址: http://get.adobe.com/cn/flashplay ...

  5. JVM监控常用命令行工具

    jps jps -mlv //列出正在运行的虚拟机进程 jstat jstat -gc pid //监视java堆状况 显示列名 具体描述 S0C 年轻代中第一个survivor(幸存区)的容量 (字 ...

  6. Dubbo 用户手册学习笔记 —— Dubbo架构

    Dubbo的架构 节点角色说明 节点 角色说明 Provider 服务提供方 Consumer 服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数和调用时间的监 ...

  7. (ubuntu) pip install scandir 时出现错误 fatal error: Python.h: No such file or directory

    安装 jupyter时遇到这个问题,在这里查到了解决方法,特记录一下. 解决方式为: 先安装 python-dev: $ sudo apt-get install python-dev 然后再安装需要 ...

  8. Matlab处理数据导出Paraview可读的vtk文件(一)

    Paraview是一个开源的可视化软件. 用到matlab子程序从这里下载 或者到博客末尾复制粘贴 子程序名为 vtkwrite 示例1: load mri D = squeeze(D); vtkwr ...

  9. es6字符串、数值、Math的扩展总结

    字符串的扩展 1.for...of遍历字符串 2.includes()判断字符串中是否包含某个字符串,返回bool 3.startsWith(),endsWith()分别盘对字符串的头部和尾部是否含有 ...

  10. css文本、字母、数字过长 自动换行处理

    ---恢复内容开始--- white-space: normal|pre|nowrap|pre-wrap|pre-line|inherit;white-space 属性设置如何处理元素内的空白norm ...