首页

文章

图的最小生成树算法?

发布网友 发布时间:2022-04-19 09:43

我来回答

3个回答

热心网友 时间:2023-06-21 22:14

图的生成树和最小生成树生成树(SpanningTree):如果一个图的子图是一个包含图所有节点的树,那这个子图就称为生成树.

热心网友 时间:2023-06-21 22:15

普利姆(prim)算法:
定义
普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图。

普利姆的算法如下:

图的顶点集合为V,设置一个顶点集合new_V,很明显new_V是V的一部分,设另一部分为other_V。

在new_V顶点与other_V顶点形成的所有边中,选择权值最小的一条,将该边的在other_V中的顶点移至new_V中,重复操作,直到new_V集合等于V集合,此时other_V为空,操作结束。
import java.util.*;
class t{
public static void main(String[] args){
char[] vertex=new char[]{'A','B','C','D','E','F','G'}; //顶点数组
int[][] ad_matrix=new int[7][];//邻接矩阵
final int N=65535;
ad_matrix[0]=new int[]{N,5,7,N,N,N,2};
ad_matrix[1]=new int[]{5,N,N,9,N,N,3};
ad_matrix[2]=new int[]{7,N,N,N,8,N,N};
ad_matrix[3]=new int[]{N,9,N,N,N,4,N};
ad_matrix[4]=new int[]{N,N,8,N,N,5,4};
ad_matrix[5]=new int[]{N,N,N,4,5,N,6};
ad_matrix[6]=new int[]{2,3,N,N,4,6,N};
Graph G=new Graph(vertex,ad_matrix); //构建图对象
//上述为测试用例
G.minimal();//最小生成树
}
}
class Graph{
private char[] vertex; //顶点数组
private int[][] ad_matrix;//邻接矩阵
private Vi_vertex vi;//已访问顶点集合
public Graph(char[] vertex,int[][] ad_matrix){
this.vertex=vertex;
this.ad_matrix=ad_matrix;
this.vi=new Vi_vertex(vertex.length);
}
public void minimal(){//最小生成树
vi.add(0);//选择下标为0的顶点作为出发顶点
while(!vi.done()){
prim();
}
}
private void prim(){//普利姆算法
int min=65535,index_x=0,index_y=0;
for(int i=0;i<vi.length();i++){
index_x=vi.get(i);
for(int j=0;j<ad_matrix[index_x].length;j++){
if(!vi.in(j)&&ad_matrix[index_x][j]<min){//顶点未被访问且边长较小
min=ad_matrix[index_x][j];//这里没有统计最小生成树的权值
index_y=j;//记录最小边位置
}
}
}
vi.add(index_y);
System.out.println(vertex[index_y]);
}
}
class Vi_vertex{//已访问顶点集合
private int[] visited;//已经存在的顶点集合
private int index=0;//顶点集合容量下标
public Vi_vertex(int length){
visited=new int[length];
}
public int length(){
return index;
}
public boolean in(int f){//判断顶点是否在已存在集合中
int i=0;
while(i<index){
if(visited[i]==f){
return true;
}
i++;
}
return false;
}
public void add(int f){//添加顶点到集合中
visited[index++]=f;
}
public boolean done(){//判断是否操作结束
return index==visited.length;//集合中保存所有顶点
}
public int get(int i){
return visited[i];
}

————————————————
克鲁斯卡尔(kruskal)算法:
基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路。
具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回路,直至森林变成一棵树为止。

#include "stdio.h"
#include "stdlib.h"
#define MAX_VERtEX_NUM 20
#define VertexType int
typedef struct edge{
VertexType initial;
VertexType end;
VertexType weight;
}edge[MAX_VERtEX_NUM];
//定义辅助数组
typedef struct {
VertexType value;//顶点数据
int sign;//每个顶点所属的集合
}assist[MAX_VERtEX_NUM];

assist assists;

//qsort排序函数中使用,使edges结构体中的边按照权值大小升序排序
int cmp(const void *a,const void*b){
return ((struct edge*)a)->weight-((struct edge*)b)->weight;
}
//初始化连通网
void CreateUDN(edge *edges,int *vexnum,int *arcnum){
printf("输入连通网的边数:\n");
scanf("%d %d",&(*vexnum),&(*arcnum));
printf("输入连通网的顶点:\n");
for (int i=0; i<(*vexnum); i++) {
scanf("%d",&(assists[i].value));
assists[i].sign=i;
}
printf("输入各边的起始点和终点及权重:\n");
for (int i=0 ; i<(*arcnum); i++) {
scanf("%d,%d,%d",&(*edges)[i].initial,&(*edges)[i].end,&(*edges)[i].weight);
}
}
//在assists数组中找到顶点point对应的位置下标
int Locatevex(int vexnum,int point){
for (int i=0; i<vexnum; i++) {
if (assists[i].value==point) {
return i;
}
}
return -1;
}
int main(){

int arcnum,vexnum;
edge edges;
CreateUDN(&edges,&vexnum,&arcnum);
//对连通网中的所有边进行升序排序,结果仍保存在edges数组中
qsort(edges, arcnum, sizeof(edges[0]), cmp);
//创建一个空的结构体数组,用于存放最小生成树
edge minTree;
//设置一个用于记录最小生成树中边的数量的常量
int num=0;
//遍历所有的边
for (int i=0; i<arcnum; i++) {
//找到边的起始顶点和结束顶点在数组assists中的位置
int initial=Locatevex(vexnum, edges[i].initial);
int end=Locatevex(vexnum, edges[i].end);
//如果顶点位置存在且顶点的标记不同,说明不在一个集合中,不会产生回路
if (initial!=-1&& end!=-1&&assists[initial].sign!=assists[end].sign) {
//记录该边,作为最小生成树的组成部分
minTree[num]=edges[i];
//计数+1
num++;
//将新加入生成树的顶点标记全不更改为一样的
for (int k=0; k<vexnum; k++) {
if (assists[k].sign==assists[end].sign) {
assists[k].sign=assists[initial].sign;
}
}
//如果选择的边的数量和顶点数相差1,证明最小生成树已经形成,退出循环
if (num==vexnum-1) {
break;
}
}
}
//输出语句
for (int i=0; i<vexnum-1; i++) {
printf("%d,%d\n",minTree[i].initial,minTree[i].end);
}
return 0;
}

热心网友 时间:2023-06-21 22:15

求图的最小生成树的算法有两种:
1.Kruskal算法(相对最好)
此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。
1. 把图中的所有边按代价从小到大排序;
2. 把图中的n个顶点看成独立的n棵树组成的森林;
3. 按权值从小到大选择边,所选的边连接的两个顶点ui,vi,应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。
4. 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。

2.Prim算法(基于贪心)
此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。
图的所有顶点集合为V;初始令集合u={s},v=V−u;在两个集合u,v能够组成的边中,选择一条代价最小的边(u0,v0),加入到最小生成树中,并把v0并入到集合u中。
重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。
由于不断向集合u中加点,所以最小代价边必须同步更新;需要建立一个辅助数组closedge,用来维护集合v中每个顶点与集合u中最小代价边信息。
ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 “君不见巴丘古城如培塿”的出处是哪里 带“奈何”的诗句大全(229句) 里翁行()拼音版、注音及读音 带“不虑”的诗句 “鲁肃当年万人守”的出处是哪里 无尘防尘棚 进出口报关流程,越详细越好。谢谢大家指教。 双线桥不是看化合价升多少就标多少的吗?为什么CL2+2KI=2KCL+I2中I失... 出师表高锰酸钾有画面了吗 2021年幼儿园新学期致家长一封信 电脑屏幕一条黑线怎么办? 销售代理商销售代理商的特点 商业代理商业代理的特征 如何看微信有没有开通微众银行 为什么微众没有开户 微众银行怎么开户 微众银行APP开户流程是什么? 唐古拉山海拔唐古拉山海拔是多少 怎么看待取消跳广场舞的人的退休金 如何选购新鲜的蓝田水柿? 恭城水柿柿树作用 创维洗衣机使用教程 创维全自动洗衣机怎么使用 自动开门器 狗羊属相婚姻相配吗 3岁的小孩不会说话怎么办 3岁孩子不会说话,应该挂什么科? 3岁小孩不会说话正常吗 鹿茸炖乌鸡怎么做? 新型冠状肺炎吃什么药可以预防 冰箱上电后一直响 食品生产许可证编号开头为“ G”。 求图的生成树的算法有哪些? 图的建立 C语言图的创建和遍历算法,紧急 图的算法 数据结构 图的创建与访问算法 图的算法实现 急急急~~~~~~~~~ 数据结构中图的建立及算法实现 索尼电视机型号有什么含义 索尼电视机型号如何表示 sony是电视的什么牌子 索尼电视怎么样 索尼电视语音为啥叫小微 索尼电视的质量和效果怎样? 日本的索尼电视怎么调制成中国语言啊。求解 索尼电视语音开机要喊好多次是什么原因 索尼4K HDR OLED电视A9F有语音功能么? 索尼电视智能语音助手设置 索尼电视语音搜索允许权限怎么设置? 索尼电视机语音更新到新版本7.4.2可以吗? 索尼电视怎么调成中文? 404 Not Found 图的算法中, 数据结构课程设计题目,图的建立以及遍历。 数据结构中图的建立及输出的课程设计 图的所有生成树的算法 404 Not Found 数据结构的图的算法 一般图形voronoi图的自动生成算法怎么做? 图算法 c++ 手机系统异常是什么意思 常用的会计软件有哪些? 初级会计电算化 会计软件的生命周期分为哪几个阶段,并简述 会计电算化和会计软件的名词解释 专业会计软件的名词解释是什么 和会计软件是一个么 谁有免费破解版的财务软件(中小企业) 我国会计软件行业急待解决的几个问题 软件的破解版,和没破解版的什么区别? 有没有破解版能用的会计软件? 我国当前管理型会计软件应用遇到的主要问题是什么?如何解决 财务软件哪些好用(免费的或者破解版)
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com