定义

连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。

强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。

连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。

生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。

最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。

kruskal算法

此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。

1. 把图中的所有边按代价从小到大排序;

2. 把图中的n个顶点看成独立的n棵树组成的森林;

3. 按权值从小到大选择边,所选的边连接的两个顶点ui,viui,vi,应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。

4. 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。

prim算法

此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。

1. 图的所有顶点集合为VV;初始令集合u={s},v=V−uu={s},v=V−u;

2. 在两个集合u,vu,v能够组成的边中,选择一条代价最小的边(u0,v0)(u0,v0),加入到最小生成树中,并把v0v0并入到集合u中。

3. 重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。

kruskal算法:

#include <iostream>
#include <list>
#include <vector>
#include <algorithm> const int INFINITE = 0x7FFFFFFF;
const int VERTEX = ;
const char szVertex[] = { 'A', 'B', 'C', 'D', 'E', 'F' }; struct stEdge
{
int u;
int v;
int weight; stEdge(int iu, int iv, int iweight):u(iu),v(iv),weight(iweight) {} friend bool operator<(const stEdge &a, const stEdge &b) { return a.weight < b.weight; }
}; void createGraph(int (*g)[VERTEX])
{
for (int i = ; i < VERTEX; i++)
{
for (int j = ; j < VERTEX; j++)
{
g[i][j] = INFINITE;
}
}
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
} void initEdges(std::vector<stEdge> &edges, const int (*g)[VERTEX])
{
for (int i = ; i < VERTEX; ++i)
{
for (int j = i+; j < VERTEX; ++j)
{
edges.push_back(stEdge(i,j,g[i][j]));
}
}
std::sort(edges.begin(), edges.end(), std::less<stEdge>());
} bool notSameTree(int u, int v, std::vector<std::list<int> > &trees)
{
int uindex = -, vindex = -; for (int i = ; i < VERTEX; ++i)
{
if (std::find(trees[i].begin(), trees[i].end(), u) != trees[i].end())
{
uindex = i;
}
if (std::find(trees[i].begin(), trees[i].end(), v) != trees[i].end())
{
vindex = i;
}
} if (uindex != vindex)
{
trees[uindex].splice(trees[uindex].end(), trees[vindex]);
return true;
} return false;
} void kruskal(const int (*g)[VERTEX])
{
std::vector<stEdge> edges;
initEdges(edges, g); std::vector<std::list<int> > trees(VERTEX);
for (int i = ; i < VERTEX; ++i)
{
trees[i].push_back(i);
} for (auto e : edges)
{
if (notSameTree(e.u, e.v, trees))
{
std::cout << szVertex[e.u] << "---" << szVertex[e.v] << std::endl;
}
}
} int main()
{
int g[VERTEX][VERTEX] = {}; createGraph(g); kruskal(g); return ;
}

prim算法:

#include <iostream>
#include <list>
#include <vector>
#include <algorithm> const int INFINITE = 0x7FFFFFFF;
const int VERTEX = ;
const char szVertex[] = { 'A', 'B', 'C', 'D', 'E', 'F' }; struct stEdge
{
int index;
int weight;
}; void createGraph(int (*g)[VERTEX])
{
for (int i = ; i < VERTEX; i++)
{
for (int j = ; j < VERTEX; j++)
{
g[i][j] = INFINITE;
}
}
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
g[][] = ; g[][] = ; g[][] = ;
} int minIndex(const stEdge *weightArr, int len)
{
int min = INFINITE;
int idx = -; for (int i = ; i < len; ++i)
{
if (weightArr[i].weight != && min > weightArr[i].weight)
{
min = weightArr[i].weight;
idx = i;
}
} return idx;
} void prim(const int (*g)[VERTEX], int index)
{
stEdge weightArr[VERTEX]; weightArr[index].weight = ;
weightArr[index].index = index;
for (int i = ; i < VERTEX; ++i)
{
if (i != index)
{
weightArr[i].index = index;
weightArr[i].weight = g[index][i];
}
} for (int i = ; i < VERTEX; ++i)
{
int nextIndex = minIndex(weightArr, VERTEX);
if (nextIndex != -)
{
std::cout << szVertex[weightArr[nextIndex].index] << "---" << szVertex[nextIndex] << std::endl; weightArr[nextIndex].weight = ;
weightArr[nextIndex].index = nextIndex;
for (int j = ; j < VERTEX; ++j)
{
if (weightArr[j].weight != && g[nextIndex][j] < weightArr[j].weight)
{
weightArr[j].index = nextIndex;
weightArr[j].weight = g[nextIndex][j];
}
}
}
}
} int main()
{
int g[VERTEX][VERTEX] = {}; createGraph(g); prim(g, ); return ;
}

转载自:https://blog.csdn.net/luoshixian099/article/details/51908175

最小生成数kruskal算法和prim算法的更多相关文章

  1. Algorithm --> Kruskal算法和Prim算法

    最小生成树之Kruskal算法和Prim算法 Kruskal多用于稀疏图,prim多用于稠密图. 根据图的深度优先遍历和广度优先遍历,可以用最少的边连接所有的顶点,而且不会形成回路.这种连接所有顶点并 ...

  2. 求最小生成树——Kruskal算法和Prim算法

    给定一个带权值的无向图,要求权值之和最小的生成树,常用的算法有Kruskal算法和Prim算法.这两个算法其实都是贪心思想的使用,但又能求出最优解.(代码借鉴http://blog.csdn.net/ ...

  3. 最小生成树之Kruskal算法和Prim算法

    依据图的深度优先遍历和广度优先遍历,能够用最少的边连接全部的顶点,并且不会形成回路. 这样的连接全部顶点并且路径唯一的树型结构称为生成树或扩展树.实际中.希望产生的生成树的全部边的权值和最小,称之为最 ...

  4. 最小生成树(次小生成树)(最小生成树不唯一) 模板:Kruskal算法和 Prim算法

    Kruskal模板:按照边权排序,开始从最小边生成树 #include<algorithm> #include<stdio.h> #include<string.h> ...

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

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

  6. 最小生成树的两种方法(Kruskal算法和Prim算法)

    关于图的几个概念定义: 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图. 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连 ...

  7. Prim算法和Dijkstra算法的异同

    Prim算法和Dijkstra算法的异同 之前一直觉得Prim和Dijkstra很相似,但是没有仔细对比: 今天看了下,主要有以下几点: 1: Prim是计算最小生成树的算法,比如为N个村庄修路,怎么 ...

  8. mahout中kmeans算法和Canopy算法实现原理

    本文讲一下mahout中kmeans算法和Canopy算法实现原理. 一. Kmeans是一个很经典的聚类算法,我想大家都非常熟悉.虽然算法较为简单,在实际应用中却可以有不错的效果:其算法原理也决定了 ...

  9. 使用Apriori算法和FP-growth算法进行关联分析

    系列文章:<机器学习实战>学习笔记 最近看了<机器学习实战>中的第11章(使用Apriori算法进行关联分析)和第12章(使用FP-growth算法来高效发现频繁项集).正如章 ...

随机推荐

  1. kafka存储机制以及offset

    1.前言 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一.下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及实际应用 ...

  2. 3.HTML DOM

    介绍 DOM(Document Object Model)文档对象模型,定义了访问 HTML 和 XML 文档的标准,它允许程序和脚本动态地访问和更新文档的内容.结构和样式. 那显然,HTML DOM ...

  3. ActiveMQ实例2--Spring JMS发送消息

    参考文章:http://my.oschina.net/xiaoxishan/blog/381209#OSC_h3_7 一,步骤参照参考文献 二.新建的项目 三.补充 web.xml <?xml ...

  4. 零基础逆向工程33_Win32_07_创建线程

    1 什么是线程(Threads)? 什么是多线程? 怎么在windows中观察多线程? 线程可以简单理解为主程序为解决一个问题而选择的其中一条路线. 同理,多线程就是同时选择不同的路线来解决此问题. ...

  5. spring笔记3-AOP

    一.概述 AOP:(Aspect Oriented Programming)即:面向切面编程.把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法 ...

  6. Linux系统错误码对照表

    C Name Value Description EPERM 1 Operation not permitted ENOENT 2 No such file or directory ESRCH 3 ...

  7. 科大讯飞语音转文字以及中文分词的Java测试代码

    我录了一段音存储在这个test.m4a文件里,语音内容为"测试一下Netweaver对于并发请求的响应性能". 使用如下Java代码进行测试: package com.iflyte ...

  8. springboot实现邮件发送

    1.创建springboot项目. 2.创建好的项目如图: 在static目录下新建index.html. 3.点击启动项目 在浏览器的地址栏中访问:http://localhost:8080/ 访问 ...

  9. eplise一键集成工具

    因为要做平台,后台的内容就由我负责,目前想让测试人员  在本地使用eplise可以进行脚本开发,但是很多人都死在了搭建环境的道路上,那我就做了一键集成,点击就可以把所需要的配置项进行配置,总结:实际就 ...

  10. Spring Security 之集群Session配置

    1.   新建Maven项目 cluster-session 2.   pom.xml <project xmlns="http://maven.apache.org/POM/4.0. ...