Prim算法:
设图G =(V,E),其生成树的顶点集合为U。
①、把v0放入U。
②、在所有u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树。
③、把②找到的边的v加入U集合。如果U集合已有n个元素,则结束,否则继续执行②。
其算法的时间复杂度为O(n^2)
#define MAXN
bool flag[MAXN];
double graph[MAXN][MAXN]; // graph[i][j] 表示节点i到j的距离
double Prim(int n) // 一共n个节点
{
int i, j, k;
double t, lowcase[105], ans = 0;
for (i = 2; i <= n; i++)
lowcase[i] = graph[1][i], flag[i] = false;
flag[1] = true;
for (i = 1; i < n; i++)
{
k = 1;
t = INF;
for (j = 2; j <= n; j++)
if (!flag[j] && lowcase[j] < t)
k = j, t = lowcase[j];
ans += t;
flag[k] = true;
for (j = 1; j <= n; j++)
if (!flag[j] && graph[k][j] < lowcase[j])
lowcase[j] = graph[k][j];
}
return ans;
}
Kruskal算法:
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
// 并查集
class UFSet
{
int n;
int *root;
public:
~UFSet();
UFSet(int n);
int Find(int x);
void Merge(int x, int y);
}*ufset;
UFSet::UFSet(int n)
{
this->n = n;
root = new int[n+1];
for (int i = 0; i < n; i++)
root[i] = i;
}
UFSet::~UFSet()
{
delete[] root;
}
int UFSet::Find(int x)
{
int t, r = root[x];
while (root[r] != r) r = root[r];
while (root[x] != r) // 路径压缩
{
t = root[x];
root[x] = r;
x = t;
}
return r;
}
void UFSet::Merge(int x, int y)
{
int fx = Find(x);
int fy = Find(y);
if (fx != fy) root[fx] = fy;
}
// 边
struct Edge
{
int left;
int right;
double dis;
bool operator < (const Edge& e) const
{
return dis < e.dis;
}
bool operator > (const Edge& e) const
{
return dis > e.dis;
}
}e;
// 边集合
priority_queue<Edge, vector<Edge>, greater<Edge> > pq;
double Kruskal(int n)
{
double ans = 0;
while (!pq.empty())
{
e = pq.top();
pq.pop();
int fx = ufset->Find(e.left);
int fy = ufset->Find(e.right);
if (fx != fy)
{
ufset->Merge(e.left, e.right);
ans += e.dis;
}
}
return ans;
}
分享到:
相关推荐
prim算法 Kruskal算法分别实现最小生成树
图论算法:最小生成树——Prim算法和Kruskal算法C 实现
Prim算法与Kruskal算法 求最小生成树 源代码 实验报告 完整
详细的c语言实现最小生成树的prim算法和kruskal算法,非常有用的
分别利用prim算法和kruskal算法实现求图的最小生成树 C++描述
建立一个图,其存储方式采用邻接矩阵形式,利用普里姆算法和克鲁斯卡尔算法求网的最小生成树,按顺序输出生成树中各条边以及它们的权值。
(1)、实验题目:给定一个地区的n 个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并得到的最小生成树的代价。 (2)、实验要求: 1、城市间的距离网采用的邻接矩阵表示,邻接矩阵的存储结构定义采用...
prim和kruskal算法求最小生成树
图的深度优先搜索,广度优先搜索,最小生成树算法,包括kruskal、prim算法的代码,以及详细的注释。深度优先应用递归、广度优先搜索利用队列、kruskal利用STL中的关联容器set、prim算法利用二叉堆结构进行优化。
Prim与Kruskal算法的最小生成树matlab实现
权值和最小的生成树就是最小生成树。 从最小生成树的定义可知,构造有n个结点的无向连通带权图的最小生成树,必须满足以下三条: (1)构造的最小生成树必须包括n个结点; (2)构造的最小生成树中有且只有n-1条边;...
最小生成树算法Prim & Kruskal ,时间复杂度 O(VlgE)
重点掌握:最小生成树(Prim算法和Kruskal算法)、单源最短路径(Dijkstra算法)。 编程实现最小生成树(Prim算法和Kruskal算法)、单源最短路径(Dijkstra算法)代码。
最小生成树算法(Prim Kruskal)
最小生成树kruskal算法并查集版 C语言实现 - Slyar Home
最小生成树(Prim,Kruskal)C++代码实现 (可运行,含测试用例,有输出,注释详细) 对于一个带权连通图,生成树不同,树中各边上权值总和也不同,权值总和最小的生成树则称为图的最小生成树。
带权图的多种算法(有向图,无向图,Dijkstra算法,到每个顶点的最短距离,佛洛依德算法(Floyd),找出每对顶点的最短路径,带权重无向图最小生成树,prim算法,Kruskal算法求最小生成树)java实现, 有注释,简单...
两种经典的最小生成树算法的代码实现,其中Kruskal算法借鉴百度文库上Kruskal的代码,Prim算法是自己写的,经过vs测试过的,可以在vs直接运行
自己写的最小生成树算法,包括prim算法,和kruskal算法。
问题描述:给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。 基本要求: 1.城市间的距离网采用邻接矩阵表示,邻接矩阵的存储结构定义采用课本中给出的...