求助求助求助~ 最小生成树问题

zhuxiaoxiand 2012-06-25 09:31:39
若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。如何以最低的经济代
价建设这个通信网,是一个网的最小生成树问题。
【基本要求】
(1)利用克鲁斯卡尔算法求网的最小生成树。
(2)实现教科书6.5 节中定义的抽象数据类型MFSet。以此表示构造生成树过程中的连通
分量。
(3)利用堆排序(参见教科书10.4.3节)实现选择权值最小的边。
(4)以文本形式输出生成树中各条边以及他们的权值。
【实现提示】
通信线路一旦建立,必然是双向的。因此,构造最小生成树的网一定是无向网。设图的
顶点数不超过30 个,并为简单起见,网中边的权值设成小于100的整数,可利用C++语言
提供的随机数函数产生。
图的存储结构的选取应和所作操作相适应。为了便于选择权值最小的边,此题的存储结
构既不选用邻接矩阵的数组表示法,也不选用邻接表,而是以存储边(带权)的一维数组表示
图。
C++实现!!
...全文
233 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuxiaoxiand 2012-06-26
  • 打赏
  • 举报
回复 1
#include"time.h"
#include"stdlib.h"
#include"stdio.h"
#include <string.h>
#define MAXE 100
int e,array[20];
struct edges
{
int bv;
int tv;
int w;
};
typedef struct edges edgeset;
int seeks(int set[],int v)
{
int i;
i=v;
while(set[i]>0)
i=set[i];
return i;
}
void kruskal(edgeset ge[],int n,int e)
{
int set[MAXE],v1,v2,i,j;
for(i=1;i<n+1;i++)
set[i]=0;
i=1;
j=1;
while(j<=e&&i<=n-1)
{
v1=seeks(set,ge[j].bv);
v2=seeks(set,ge[j].tv);
if(v1!=v2)
{
printf("(%d,%d):%d\n",ge[j].bv,ge[j].tv,ge[j].w);
set[v1]=v2;
i++;
}
j++;
}
}
void insertsort(edgeset ge[],int e)
{
int i,j;
for(i=2;i<=e;i++)
if(ge[i].w<ge[i-1].w)
{
ge[0]=ge[i];
j=i-1;
while(ge[0].w<ge[j].w)
{
ge[j+1]=ge[j];
j--;
}
ge[j+1]=ge[0];
}
}



void adjustMinHeap(int *a, int pos, int len){
int temp;
int child;
for (temp = a[pos]; 2 * pos + 1 <= len; pos = child){
child = 2 * pos + 1;
if (child < len && a[child] > a[child + 1])
child++;
if (a[child] < temp){ //再这儿把temp写成了a[pos], 显然应该是待调整的节点,因为如果元素不能往下流动,则退出。。。
a[pos] = a[child];
}
else {
break;
}
}
a[pos] = temp;
}

void minHeapSort(int *a)
{
int i;

for (i = e/2 - 1; i >= 0; i--)
adjustMinHeap(a, i, e - 1);
for (i = e - 1; i >= 0; i--){
//printf("%d ", a[0]);
int temp = a[0];
a[0] = a[i];
a[i] = temp;
adjustMinHeap(a, 0, i - 1);
}
}
void main()
{
printf("\n\n\n\n") ;
for(int m=0;m<10;m++)
printf(" ");
printf("************************************\n\n");
for( m=0;m<10;m++)
printf(" ");
printf("* 第八题:最小生成树问题: *\n\n");
for( m=0;m<10;m++)
printf(" ");
printf("************************************\n\n");
rand((unsigned)time(0));
edgeset ge[MAXE];
int a,N,i,r;
printf("请输入顶点个数:");
scanf("%d",&N);
printf("请输入边的条数:");
scanf("%d",&e);
printf("请输入边的信息(起点,终点),边的权值将自动生成:\n");
for(i=1;i<=e;i++)
{
scanf("%d,%d",&ge[i].bv,&ge[i].tv);
r=rand()%10000 ;
ge[i].w=r/10;
}
printf("系统随机产生各个边的权值后前后顶点以及他们之间\n的边的权值如下:(前顶点,后顶点,权值)\n");
for(i=1;i<=e;i++)
printf("%d,%d,%d\n",ge[i].bv,ge[i].tv,ge[i].w);
printf("\n\n");

//进入堆排序
for( i=0;i<e;i++)
array[i]=ge[i+1].w ;
minHeapSort(array);
printf("堆排序后权值从大到小输出如下\n");
for (i = 0; i < e; i++)
printf("%d ", array[i]);
printf("\n\n权值最小的边是:%d \n",array[e-1]);
printf("\n");
printf("克鲁斯卡尔算法求出最佳路径是:(格式如右面:<城市a,城市b>:路程)\n");
insertsort(ge,e);
kruskal(ge,N,e);

}
这个程序做好之后还是有点问题,帮忙解决一下吧。
W170532934 2012-06-26
  • 打赏
  • 举报
回复
作业贴啊!
zyb_debug 2012-06-26
  • 打赏
  • 举报
回复
大牛,遇到这种学术性的东西我就搞不定了。。
hen_hao_ji 2012-06-25
  • 打赏
  • 举报
回复
kruska算法
以存储边(带权)的一维数组表示图:
struct ed
{
int u; //起始点
int v; //终结点
int w; //权重
};
参考:
http://zhidao.baidu.com/question/222120267.html?fr=qrl&index=4

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧