最小生成树(prim)
里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。
介绍如下:
http://baike.baidu.com/link?url=nDhHyOlu8i90Hm5bjUycarVdBPN8BXQvnv8NGwl0g4MLlLkmkFLwf7xs1-JBWCRkQw5qDU6cIwh1ov7fyRRxQK
原理可以参考这几篇文章:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html
http://blog.csdn.net/weinierbian/article/details/8059129
http://blog.chinaunix.net/uid-25324849-id-2182922.html
prim算法适合稠密图,邻接矩阵时间复杂度为O(n^2),邻接表为O(eloge),其时间复杂度与边得数目无关。
而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。
邻接矩阵实现:
#include <iostream>
using namespace std; #define MAXVEX 20
#define MAXEDGE 20
#define INFINITY 65535 typedef struct
{
int vexs[MAXVEX];
int arc[MAXVEX][MAXVEX];
int numVertexes,numEdges;
}MGraph; typedef int Patharc[MAXVEX];
typedef int ShortPathTable[MAXVEX]; bool visited[MAXVEX];//保存已访问的数组
int father[MAXVEX];
int closeset[MAXVEX]; void CreateGraph(MGraph* G)
{
cout<<"请输入边数和顶点数:\n";
int d,n,i,j;
cin>>d>>n;
G->numVertexes = n;
G->numEdges = d; //给顶点和边初始化
for(i = ;i<G->numVertexes;i++)
G->vexs[i] = i;
for(i = ;i<G->numVertexes;i++)
{
for(j = ;j<G->numVertexes;j++)
{
if(i==j)
G->arc[i][j] = ;
else
G->arc[i][j] = G->arc[j][i] = INFINITY;
}
} G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=; for(i = ;i<G->numVertexes;i++)
{
for(j = i;j<G->numVertexes;j++)
{
G->arc[j][i] = G->arc[i][j];
}
}
} int prim(MGraph G, Patharc *P, ShortPathTable *D)
{
int v,w; //init
for(v = ;v<G.numVertexes;v++)
{
visited[v] = false;
(*D)[v] = G.arc[][v];
father[v] = -;
closeset[v] = ;
}
visited[] = true; int len = ;
int nlen,nid; //求得下一个符合条件的点
for(v = ;v<G.numVertexes;v++)
{
nlen = INFINITY;
for(w = ;w<G.numVertexes;w++)
{
if(!visited[w] && (*D)[w]<nlen)
{
nlen = (*D)[w];
nid = w;
}
} len += nlen;
visited[nid] = true;
father[nid] = closeset[nid]; for(w = ;w<G.numVertexes;w++)
{
if(!visited[w] && (*D)[w]>G.arc[nid][w])
{
(*D)[w] = G.arc[nid][w];
closeset[w] = nid;
}
} } return len; } int main()
{
int v0,i,j; MGraph G; Patharc P;
ShortPathTable D; CreateGraph(&G); int d = prim(G,&P,&D); cout<<"最小树如下:\n";
for(i = ;i<G.numVertexes;i++)
{
cout<<"("<<i<<","<<father[i]<<") ";
}
cout<<endl; cout<<"最短路径长度为:\n"; cout<<d<<endl; return ; }
我是用vector和pair的邻接表实现的,然后用两个list保存两个集合,一个最小生成树集,一个其他集
实现如下:
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std; vector<pair<int,int> > eg[]; vector<pair<int,int> > result; typedef pair<int,int> pa; bool visit[]; list<int> setOfPrim; list<int> outOfPrim; int lowcost[] = {}; void prim(int n,int d)
{
int min,aim,sta;
bool is; list<int>::iterator sop;//最小树集合
list<int>::iterator oop;//其他集合
vector<pair<int,int> >::iterator it; setOfPrim.push_back();//放入起始点0进最小树集合 //初始化其他集合
for(int i = ;i<n;i++)
outOfPrim.push_back(i); while(!outOfPrim.empty())//其他集合不为空
{
//遍历最小树集合,sop,寻找与集合最近的点
min = <<;
for(sop = setOfPrim.begin();sop!=setOfPrim.end();sop++)
{
//遍历sop邻接点
for(int i = ;i<eg[*sop].size();i++)
{
pa x = eg[*sop][i];
is = false; //如果点属于oop集合
for(oop = outOfPrim.begin();oop!=outOfPrim.end();oop++)
{
if(*oop == x.first)
{
is = true;
}
} if(is)
{
if(x.second<min)
{
min = x.second;
aim = x.first;
sta = *sop;
}
//min存放了离sop集合最近的点的距离
//aim存放了点的序号
}
}
} setOfPrim.push_back(aim);
result.push_back(make_pair(sta,aim));
for(oop = outOfPrim.begin(); oop != outOfPrim.end(); )
{
if(*oop == aim)
{
oop = outOfPrim.erase(oop);
if(outOfPrim.empty())
break;
}
else
oop++;
}
cout<<"The set of prim:\n";
for(sop = setOfPrim.begin(); sop != setOfPrim.end();sop++)
{
cout<<*sop<<" ";
}
cout<<"\nThe set of not prim:\n";
for(oop = outOfPrim.begin(); oop != outOfPrim.end();oop++)
{
cout<<*oop<<" ";
}
cout<<endl; for(it = result.begin();it!=result.end();it++)
{ cout<<"("<<(*it).first<<","<<(*it).second<<")";
}
cout<<endl<<endl;
}
} int main()
{
int n,d;
cin>>n>>d;
for(int i = ;i<d;i++)
{
int t,s,w;
cin>>t>>s>>w;
eg[t].push_back(make_pair(s,w));
eg[s].push_back(make_pair(t,w));
}
prim(n,d); }
/*
6 8
0 1 2
0 3 4
1 4 4
2 0 5
2 5 2
3 4 3
3 5 7
5 4 3
*/
另外,因为prim算法和Dijkstra算法很像,这篇文章有讲两者之间的区别:
http://www.cnblogs.com/CheeseZH/archive/2012/10/09/2717106.html
最小生成树(prim)的更多相关文章
- 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。
//归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...
- 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...
- 最小生成树Prim算法(邻接矩阵和邻接表)
最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...
- 转载:最小生成树-Prim算法和Kruskal算法
本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...
- 最小生成树Prim
首先解释什么是最小生成树,最小生成树是指在一张图中找出一棵树,任意两点的距离已经是最短的了. 算法要点: 1.用book数组存放访问过的节点. 2.用dis数组保存对应下标的点到树的最近距离,这里要注 ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- 最小生成树Prim算法和Kruskal算法
Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...
- 最小生成树 Prim Kruskal
layout: post title: 最小生成树 Prim Kruskal date: 2017-04-29 tag: 数据结构和算法 --- 目录 TOC {:toc} 最小生成树Minimum ...
- POJ1258 (最小生成树prim)
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 46319 Accepted: 19052 Descri ...
- poj1861 最小生成树 prim & kruskal
// poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是 #include <cstdio> #includ ...
随机推荐
- Usboot V1.68版本
V1.68版本,我的收藏之一 官方的介绍: 市面上现在大多数U盘都支持启动机器的功能,但是要制作启动型U盘,需要进入WIN98,现在很多人机器 上都没有98了吧,呵呵.为了做个启动盘,装一个98,多冤 ...
- (三)SSO之CAS框架单点退出,退出到CAS登录界面
应需求的改变.CAS自定义登录页面不安全,不再使用,于是我一下子回到了原点,在linux上部署上了没有加自定义登陆界面的CAS,接下来开始修改CAS自己默认的登录界面为我们的界面. 一下子修改成功是根 ...
- [CSS3] 边栏导航动画
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- scrapy入门例子
使用爬取http://quotes.toscrape.com/内容,网站内容很简单 一. 使用scrapy创建项目 scrapy startproject myscrapy1 scrapy gensp ...
- 异步 JavaScript - 事件循环
简评:如果你对 JavaScript 异步的原理感兴趣,这里有一篇不错的介绍. JavaScript 同步代码是如果工作的 在介绍 JavaScript 异步执行之前先来了解一下, JavaScrip ...
- GCD 使用若干注意事项
这篇文章写的是看完 WWDC 17 - Modernizing GCD Usage 之后的笔记. 一.Parallelism & Concurrency Parallelism 指的是在多个 ...
- psp0级报告
计划 1.1需求描述: 现在市场上有很多的面向小学生的题卡,但是这习题卡不但价格昂贵,而且每次做题的内容基本都是固定.针对这些问题,开发出了这款网页在线答题系统,每次的题目都有所不同,可以跟快更好提高 ...
- FlowPortal-BPM——移动手机端配置与IIS发布
一.移动手机端配置 (1)VS打开文件夹iAnyWhere,配置config文件 (2)BPM-Web文件config中设置(设置为外网网址) 二.BPM设置 勾选移动审批可以设置要展示的字段信息,修 ...
- C#-WebForm-设置div边框为内边框:box-sizing:border-box;
设置div边框为内边框:box-sizing:border-box;
- Windows Server2008如何打开添加IIS服务器
https://jingyan.baidu.com/article/1612d500aa4594e20e1eeefc.html