导航:首页 > 源码编译 > 求最小生成树算法代码及运行图片

求最小生成树算法代码及运行图片

发布时间:2025-01-12 07:17:49

① 用破圈法求最小生成树

感觉上你那里的“算法基本思想”实现难度很大,因为图的连通性不好维护
找圈的话,随便找个节点为根DFS整个图,然后在这样的DFS生成树中,每条非树边都对应了一个圈,每次找一条非树边,删去所在圈中最长边生成一个新树,直到不存在非树边为止,剩下的就是最小生成树了
具体实现的时候,先求出一个DFS生成树,然后递归处理每棵子树

假设要处理的子树根节点为u,对该子树破圈法的粗略伪代码如下:

void 破圈法(u)
{
for ( v是u的每个子节点 ) 破圈法(v);
for ( e是连接u与其后继的每条非树边 )
{
v=e的另一个端点;
e'=u到v之间的最长树边;
if (w[e]>=w[e']) 删除边e;//w[e]表示e的权
else
{
//用w表示原先e'的在树中较深的端点,p[v]表示v的亲节点
删除边e';
if (v!=w)
{
将v列入u的子节点列表;
将p[v]、p[p[v]]、...、w这条路径反向,并将p[v]列入v的子节点列表;
}
}
}
}

上述过程不加优化的时间复杂度为O(VE),效率非常差
貌似其中找最长边和将v的若干祖先节点路径反向的两步优化空间比较大,或许可将整个时间复杂度下降到O(ElgV),研究中

② c加加提问,克鲁斯卡尔算法是什么

克鲁斯卡尔算法,从边的角度求网的最小生成树,时间复杂度为O(eloge)。和普里姆算法恰恰相反,更适合于求边稀疏的网的最小生成树。

对于任意一个连通网的最小生成树来说,在要求总的权值最小的情况下,最直接的想法就是将连通网中的所有边按照权值大小进行升序排序,从小到大依次选择。

由于最小生成树本身是一棵生成树,所以需要时刻满足以下两点:

③ 最小生成树算法描述

最小生成树算法的求解过程通常从一个空树开始,逐步添加边以形成一棵包含n-1条边的最小生成树。这个通用算法可以用伪代码简洁表示:



最小生成树的求解步骤如下:



这可以用Pascal、Prim算法或Kruskal算法等具体实现,它们的区别在于寻找安全边的方式不同:





(3)求最小生成树算法代码及运行图片扩展阅读

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图联通的最少的边。

④ 求最小生成树的kruska算法,效率尽量高,尽量多点注释!c++代码

/*
基本算法思想:
为使生成树上总的权值之和达到最小,则应使每一条边上的权值尽可能地小,自然应从权值最小的边选起,直至选出 n-1 条互不构成回路的权值最小边为止。
具体作法如下:首先构造一个只含 n 个顶点的森林,然后依权值从小到大从连通网中选择不使森林中产生回路的边加入到森林中去,直至该森林变成一棵树为止,这棵树便是连通网的最小生成树。
由于生成树上不允许有回路,因此并非每一条居当前权值最小的边都可选。

用并查积 和 克鲁是卡尔算法实现查找最短边
利用快排按边递增排列,每次从中选出最短边,同时将最短边的两个顶点并入到集合中
心得:利用并查积 和 kruskal算法结合找最短路径可以使查找的效率更高
加入集合中的边都是构成最小生成树的边,所以每家一次sum 都要加上这两个顶点之间的距离
*/
/*下面的代码输入n个节点,然后输入n*(n-1)/2条边及权值,输出是连通这些边的最小权值*/
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

struct ed
{
int u; //起始点
int v; //终结点
int w; //权重
};
bool cmp(ed a,ed b)
{
return a.w<b.w; //从小到大排序
}
struct ed edge[100000];
int p[105];

int find(int x) //查找x的父亲
{
while(p[x]!=x)
x=p[x];
return x;
}
int kruskal(int n)
{
int i,count=1,sum=0;
for(i=0;i<=n;i++)
p[i]=i; //并查集初始化,每个节点到父亲是自己
int x,y;
sort(edge,edge+n*(n-1)/2,cmp); //快速排序
for(i=0;count<n;i++)
{
x=find(edge[i].u); //点edge[i].u的父亲是x
y=find(edge[i].v); //点edge[i].v的父亲是y
if(x!=y) //判断是否会路
{
count++; //加上一条边
p[x]=y; //把x和y加入统一个集合
sum+=edge[i].w;
}
}
return sum;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n) //输入n个节点
{
int i;
for(i=0;i<n*(n-1)/2;i++) //输入 n*(n-1)/2条边
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); //表示点edge[i].u和点edge[i].v之间的权重为 edge[i].w
printf("%d\n",kruskal(n));
}
return 0;
}

楼主,这可是本人一个字一个字敲出来点,要给分啊

阅读全文

与求最小生成树算法代码及运行图片相关的资料

热点内容
stc1t单片机 浏览:313
英华特涡旋压缩机 浏览:4
编译码器的输入输出干扰 浏览:542
往复式压缩气缸过热的原因 浏览:839
4u服务器机箱怎么卖 浏览:461
如何自学葡萄牙语app 浏览:456
摆来摆去的游戏解压 浏览:270
centos注销命令 浏览:859
vue多端编译 浏览:755
程序员qq表白代码编辑 浏览:893
联想服务器怎么进后台 浏览:114
安卓定制rom怎么刷 浏览:539
三层交换机的配置命令 浏览:110
49算法公式 浏览:791
求最小生成树算法代码及运行图片 浏览:931
python扫雷计数 浏览:880
什么安卓手机品牌最保值 浏览:847
编程猫买房子 浏览:134
c语言系列编程 浏览:742
符合国标加密标准技术 浏览:497