最小生成树.docx

上传人:b****5 文档编号:7524510 上传时间:2023-01-24 格式:DOCX 页数:11 大小:128.78KB
下载 相关 举报
最小生成树.docx_第1页
第1页 / 共11页
最小生成树.docx_第2页
第2页 / 共11页
最小生成树.docx_第3页
第3页 / 共11页
最小生成树.docx_第4页
第4页 / 共11页
最小生成树.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

最小生成树.docx

《最小生成树.docx》由会员分享,可在线阅读,更多相关《最小生成树.docx(11页珍藏版)》请在冰豆网上搜索。

最小生成树.docx

最小生成树

最小生成树问题

【问题描述】

若要在n个城市之间建设通信网络,只需要假设n-1条线路即可。

如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。

【系统要求】

1.利用克鲁斯卡尔算法求网的最小生成树。

2.利用普里姆算法求网的最小生成树。

3.要求输出各条边及它们的权值。

【程序结构图】

 

【算法分析】

1.普里姆算法

voidMiniSpanTree_PRIM(MGraphG,intu)

{//下面用普里姆算法来实现

minsideclosedge;

inti,j,k;

k=LocateVex(G,u);

for(j=0;j

{

closedge[j].adjvex=u;

closedge[j].lowcost=G.arcs[k][j].adj;//引入了一个新的辅助数组,

}

printf("它的最小生成树权值和路径为\n");

for(i=1;i

{

k=f(closedge,G);

printf("%d%d--%d\n",closedge[k].lowcost,closedge[k].adjvex,G.vexs[k]);//输出结果

closedge[k].lowcost=0;

for(j=1;j

{

if(G.arcs[k][j].adj

{

closedge[j].adjvex=G.vexs[k];

closedge[j].lowcost=G.arcs[k][j].adj;

//这一步是更新closedge的值

}

}

}

}

2.克鲁斯卡尔算法

voidKruskal(MGraph&G)

{

memset(fa,-1,sizeof(fa));

//初始化fa数组

intcnt=0;

for(intk=0;k

{

intu=edge[k].from;

intv=edge[k].to;

intt1=find(u);//找第一个点的起始点

intt2=find(v);//找第二个点的起始点

if(t1!

=t2)

{//如果不相等,则不构成回路

fa[t1]=t2;

id[cnt]=k;

cnt++;

if(cnt==G.vexnum-1)//当已选了n-1条边时,退出循环

break;

}

}

printf("最小生成树的权值和边分别是:

\n");

for(intk=0;k

{

intt=id[k];

printf("%d%d--%d\n",edge[t].len,edge[t].from,edge[t].to);

}

}

【程序测试】

建立如下图所示的城市网络:

测试结果截图:

【源代码】

#include

#include

#include

#include

usingnamespacestd;

#defineMAXN1005//假设点数不超过

#defineINFINITY32767

#defineOK1

#defineERROR0

#defineOVERFLOW0

#defineMAX_VERTEX_NUM20

intfa[MAXN];

intid[MAXN];

structEdge

{//边的数据结构

intfrom,to;

intlen;

};

Edgeedge[MAXN*MAXN];

boolcmp(Edgel,Edger)

{//边的比较函数

returnl.len

}

intfind(intx)

{//并查集,用于判断是否与已选择的边构成环

if(fa[x]==-1)

returnx;

else

returnfa[x]=find(fa[x]);

}

typedefintVRType;

typedefintVertexType;

typedefstructArcCell

{VRTypeadj;

}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//定义的顶点的关系类型,代表不相邻1代表相邻

typedefstruct

{

VertexTypeadjvex;//abcdef

VRTypelowcost;//15488

}minside[100],mini;

 

typedefstruct

{AdjMatrixarcs;//一个邻接矩阵

VertexTypevexs[MAX_VERTEX_NUM];

//每个顶点的弧

intvexnum,arcnum;//图的当前顶点数和弧数

}MGraph;//定义了图的结构

intLocateVex(MGraphG,VertexTypeu)

{

inti;

for(i=0;i

{

if(u==G.vexs[i])

returni;

}

return-1;

}

intf(miniclosedge[100],MGraphG)

{

inti=0,k,j,min;

while(!

closedge[i].lowcost)

i++;

min=closedge[i].lowcost;

k=i;

for(j=i+1;j

if(closedge[j].lowcost>0&&min>closedge[j].lowcost)

{

min=closedge[j].lowcost;

k=j;

}

returnk;

}//找到非零该行最小的元素

voidreadin(MGraph&G)

{

intr=0;

intl=0;

intw=0;

inti,j,k;

printf("请您输入所建图的顶点数、弧数\n");

scanf("%d%d",&G.vexnum,&G.arcnum);

//getchar();

printf("请您依次输入各个顶点:

\n");

for(i=0;i

{

scanf("%d",&G.vexs[i]);

//getchar();//输入每个节点的值

}

for(i=0;i

for(j=0;j

G.arcs[i][j].adj=32767;

//将每一个节点的值都设为无穷大

printf("请输入顶点,弧,权值:

\n");

for(k=0;k

{

scanf("%d%d%d",&l,&r,&w);

edge[k].from=min(l,r);

edge[k].to=max(l,r);

edge[k].len=w;

i=LocateVex(G,l);

j=LocateVex(G,r);

G.arcs[i][j].adj=G.arcs[j][i].adj=w;//赋值的工作

}

sort(edge,edge+G.arcnum,cmp);

return;

}

 

voidKruskal(MGraph&G)

{

memset(fa,-1,sizeof(fa));

//初始化fa数组

intcnt=0;

for(intk=0;k

{

intu=edge[k].from;

intv=edge[k].to;

intt1=find(u);//找第一个点的起始点

intt2=find(v);//找第二个点的起始点

if(t1!

=t2)

{//如果不相等,则不构成回路

fa[t1]=t2;

id[cnt]=k;

cnt++;

if(cnt==G.vexnum-1)//当已选了n-1条边时,退出循环

break;

}

}

printf("最小生成树的权值和边分别是:

\n");

for(intk=0;k

{

intt=id[k];

printf("%d%d--%d\n",edge[t].len,edge[t].from,edge[t].to);

}

}

voidMiniSpanTree_PRIM(MGraphG,intu)

{//下面用普里姆算法来实现

minsideclosedge;

inti,j,k;

k=LocateVex(G,u);

for(j=0;j

{

closedge[j].adjvex=u;

closedge[j].lowcost=G.arcs[k][j].adj;//引入了一个新的辅助数组,

}

printf("它的最小生成树权值和路径为\n");

for(i=1;i

{

k=f(closedge,G);

printf("%d%d--%d\n",closedge[k].lowcost,closedge[k].adjvex,G.vexs[k]);//输出结果

closedge[k].lowcost=0;

for(j=1;j

{

if(G.arcs[k][j].adj

{

closedge[j].adjvex=G.vexs[k];

closedge[j].lowcost=G.arcs[k][j].adj;

//这一步是更新closedge的值

}

}

}

}

 

intmain()

{

intn;

do{

printf("\t\t\t主菜单\n");

printf("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

printf("\t\t\t1.创建城市通讯网\n");

printf("\t\t\t2.克鲁斯卡尔算法求最短路径\n");

printf("\t\t\t3.普里姆算法求最短路径\n");

printf("\t\t\t4.退出\n");

printf("\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

printf("请输入序号选择相应操作:

");

scanf("%d",&n);

switch(n)

{

case1:

MGraphG;readin(G);break;

case2:

Kruskal(G);break;

case3:

MiniSpanTree_PRIM(G,G.vexs[0]);break;

case4:

printf("欢迎使用\n");break;

default:

printf("输入错误");

}

}while(n!

=4);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1