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

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

发布时间: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;
}

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

阅读全文

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

热点内容
android短信验证码倒计时 浏览:641
排课走班源码 浏览:222
程序员刚毕业去了小公司有发展吗 浏览:90
速腾怎么安装安卓手机互联 浏览:143
linux设备驱动程序代码 浏览:301
服务器的功耗怎么看 浏览:651
app组件哪里找 浏览:87
androidqq红包 浏览:412
服务器如何传输 浏览:456
如何快速将多个文件夹快速解压缩 浏览:114
程序员睡前都在想什么 浏览:37
少儿编程技能培训心得 浏览:458
白命令 浏览:816
headfirstjavapdf 浏览:552
广数980t怎么编程 浏览:592
无邪app在哪里下载 浏览:462
mac自带php目录 浏览:632
海淘小程序源码 浏览:750
哪里下载苏宁秒达app 浏览:643
androidcmnet 浏览:31