最小生成树的Prim算法也是贪心算法的一大经典应用。Prim算法的特点是时刻维护一棵树,算法不断加边,加的过程始终是一棵树。

Prim算法过程:

一条边一条边地加, 维护一棵树。

初始 E = {}空集合, V = {任意节点}

循环(n – 1)次,每次选择一条边(v1,v2), 满足:v1属于V , v2不属于V。且(v1,v2)权值最小。

E = E + (v1,v2)
V = V + v2

最终E中的边是一棵最小生成树, V包含了全部节点。

以下图为例介绍Prim算法的执行过程。

Prim算法的过程从A开始 V = {A}, E = {}

选中边AF , V = {A, F}, E = {(A,F)} 

选中边FB, V = {A, F, B}, E = {(A,F), (F,B)}

选中边BD, V = {A, B, F, D},   E = {(A,F), (F,B), (B,D)}

选中边DE, V = {A, B, F, D, E},   E = {(A,F), (F,B), (B,D), (D,E)}
 
选中边BC, V = {A, B, F, D, E, c},   E = {(A,F), (F,B), (B,D), (D,E), (B,C)}, 算法结束。

最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。

 
输入

第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
输出
 
输出最小生成树的所有边的权值之和。
 
输入示例

9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
输出示例

37
 
请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
不同语言如何处理输入输出,请查看下面的语言说明。
 
 
简单的最小生成树,自己写的代码一直过不了
 
AC代码(prim算法)
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
int G[1001][1001];//邻接矩阵
int vis[1001],lowc[1001];
int prim(int G[][1001],int n){
int i,j,p,minc,res=0;
memset(vis,0,sizeof(vis));
vis[1]=1;//从1开始访问
for(i=2;i<=n;i++) lowc[i]=G[1][i];
for(i=2;i<=n;i++){
minc=inf; p=-1;
for(j=1;j<=n;j++){
if(vis[j]==0&&lowc[j]<minc){
minc=lowc[j]; p=j;
}
}
//cout<<minc<<endl;
if(inf==minc) return -1;//原图不联通
res+=minc; vis[p]=1;
for(j=1;j<=n;j++){//更新lowc[]
if(vis[j]==0&&lowc[j]>G[p][j]){
lowc[j]=G[p][j];
}
}
}
return res;
} int main()
{
int n,m;
while(cin>>n>>m){
int x,y,w;
memset(G,inf,sizeof(G));//首先记录所有边的权为inf
for(int i=1;i<=m;i++){
cin>>x>>y>>w;
G[x][y]=G[y][x]=w;
//cout<<G[x][y]<<endl;
}
//int res=prim(n);
cout<<prim(G,n)<<endl;
}
return 0;
}

  

自己写的代码不知道错哪了(kruskal算法)
#include<stdio.h>
#include<string.h>
#include<algorithm> using namespace std; struct tr
{
int s,e,w;
}p[50000+10]; bool cmp(tr x, tr y)
{
return x.w < y.w;
} int n,m;
int f[1000+10];
int i,j;
long long ans; int find(int x) //找父亲
{
int r = x;
while(f[r] != r)
r = f[r];
return r;
int i = x, j;
while(i != r)
{
j = f[i];
f[i] = r;
r = j;
}
} void join(int x, int y)
{
int fx = find(x);
int fy = find(y);
if(fx != fy)
f[fx] = fy;
} int kruskal()
{
sort(p, p+m, cmp);
for(i=0; i<n; i++)
{
f[i] == i;//初始化 父亲节点
}
for(i=0; i<n; i++)
{
if(find(p[i].s) != find(p[i].e))
{
join(p[i].e, p[i].s);
ans += p[i].w;
}
}
return ans;
} int main()
{
ans=0;
scanf("%d %d",&n,&m);
for(i=0; i<m; i++)
{
scanf("%d %d %d",&p[i].s, &p[i].e, &p[i].w);
}
kruskal();
printf("%lld\n",ans);
return 0;
}

  

 
 

Prim算法---最小生成树的更多相关文章

  1. [讲解]prim算法<最小生成树>

    最小生成树的方法一般比较常用的就是kruskal和prim算法 一个是按边从小到大加,一个是按点从小到大加,两个方法都是比较常用的,都不是很难... kruskal算法在本文里我就不讲了,本文的重点是 ...

  2. 6)图[2]Prim算法[最小生成树]

    Prim 算法 求解方法: 首先将所指定的起点作为已选顶点,然后反复在满足如下条件下的边中选择一条最小边,直到 所有顶点已成为已选顶点为止(选择n-1条边). #include "iostr ...

  3. 数据结构:最小生成树--Prim算法

    最小生成树:Prim算法 最小生成树 给定一无向带权图.顶点数是n,要使图连通仅仅需n-1条边.若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost ...

  4. 最小生成树-普利姆(Prim)算法

    最小生成树-普利姆(Prim)算法 最小生成树 概念:将给出的所有点连接起来(即从一个点可到任意一个点),且连接路径之和最小的图叫最小生成树.最小生成树属于一种树形结构(树形结构是一种特殊的图),或者 ...

  5. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  6. 最小生成树——prim算法

    prim算法是选取任意一个顶点作为树的一个节点,然后贪心的选取离这棵树最近的点,直到连上所有的点并且不够成环,它的时间复杂度为o(v^2) #include<iostream>#inclu ...

  7. 贪心算法-最小生成树Kruskal算法和Prim算法

    Kruskal算法: 不断地选择未被选中的边中权重最轻且不会形成环的一条. 简单的理解: 不停地循环,每一次都寻找两个顶点,这两个顶点不在同一个真子集里,且边上的权值最小. 把找到的这两个顶点联合起来 ...

  8. 无向图最小生成树(prim算法)

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...

  9. 最小生成树Prim算法(邻接矩阵和邻接表)

    最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...

随机推荐

  1. c# 数据集调试工具插件

    DataSetSpySetup,调试期查看dataset数据集的记录内容, Debug DataSet

  2. c++经典排序算法全集(转)

    C++排序算法全集 排序算法是一种基本并且常用的算法.由于实际工作中处理的数量巨大,所以排序算法对算法本身的速度要求很高. 一.简单排序算法 由于程序比较简单,所以没有加什么注释.所有的程序都给出了完 ...

  3. gen_projective_mosaic(Halcon例子)

    * This example program shows how several images of a PCB can be combined * into a large mosaic image ...

  4. 在coursera上有哪些值得推荐的课程

    来自知乎 https://www.zhihu.com/question/22436320/answer/224996328

  5. 【316】python.requests 读取网页信息

    参考:Python:在网页中查找字符串的一般方法--in 参考:python怎么安装requests 参考:Requests 快速上手 操作步骤如下: 添加环境变量,将 python 所在文件夹添加至 ...

  6. 使用Visual Studio进行 Android开发的十大理由

    [原文发表地址]Top 10 reasons to use Visual Studio for C++ Android Development! Visual Studio: C++跨平台的移动解决方 ...

  7. C语言文件实现学生成绩管理

    C语言实现学生成绩管理 项目简介 用C语言的链表及文件操作实现学生成绩的管理,实现主要的添加.修改.删除.查询的主要功能,并在程序关闭时将数据存储在二进制的文件中并加密.下一次打开程序,先解密二进制文 ...

  8. assetBundle打包脚本与LUA

    AssetBundles与脚本 所有Unity的AssetBundle,无论是从本地获取 还是www,或者打包整个场景.物体上的脚本都不会被编译.所以AssetBundle打包的时候即使物体上有脚本. ...

  9. springboot与消息(rabbtiMQ)

    1.大多应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦能力 1.1异步通信 1.2解耦 1.3削峰 2.消息服务中两个重要概念:       消息代理(message broker)和目的地 ...

  10. How To Check Member In Window VS With CplusPlus?

    实例说明 下面这个实例代码, 快速举例了在Win32应用程序下,对于内存的泄漏检查. 其中的原理,目前本人还是不太的理解. 只是记录了使用方法. 以后,看情况,会更新的. #ifdef _WIN32 ...