【问题描述】
北航主要办公科研楼有新主楼、逸夫楼、如心楼、办公楼、图书馆、主楼、一号楼…。北航网络中心计划要给相关建筑物间铺设光缆进行网络连通,请给出用料最少的铺设方案。
编写程序输入一个办公区域分布图及建筑物之间的距离,计算出用料最少的铺设方案(只有一组最优解,不用考虑多组解)。要求采用Prim或Kruskal算法实现。
【输入形式】
办公区域分布图的顶点(即建筑物)按照自然数(0,1,2,n-1)进行编号,从标准输入中首先输入两个正整数,分别表示线路图的顶点的数目和边的数目,然后在接下的行中输入每条边的信息,每条边占一行,具体形式如下:
<n> <e>
<id> <vi> <vj> <weight>
...
即顶点vi和vj之间边的权重是weight,边的编号是id。
【输出形式】
输出铺设光缆的最小用料数,然后另起一行输出需要铺设的边的id,并且输出的id值按照升序输出。
【样例输入】
6 10
1 0 1 600
2 0 2 100
3 0 3 500
4 1 2 500
5 2 3 500
6 1 4 300
7 2 4 600
8 2 5 400
9 3 5 200
10 4 5 600
【样例输出】
1500
2 4 6 8 9
【样例说明】
样例输入说明该分布图有6个顶点,10条边;顶点0和1之间有条边,边的编号为1,权重为600;顶点0和2之间有条边,权重为100,其它类推。其对应图如下:
经计算此图的最少用料是1500,可以使图连通,边的编号是2 4 6 8 9。其对应的最小生成树如下:
【评分标准】
通过所有测试点满分。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#define n0 30
#define INFINITY 32767
typedef struct Arcs
{
int id;
int vi;
int vj;
int weight;
} Arcs;
typedef struct AMGraph
{
int vexs_num;
int arcs_num;
int vexs[n0];
Arcs arcs[n0];
} AMGraph;
AMGraph* CreateGraph()
{
AMGraph* p=(AMGraph*)malloc(sizeof(AMGraph));
int m,n;
scanf("%d %d\n",&m,&n);
p->vexs_num=m;
p->arcs_num=n;
for(int i=0;i<p->vexs_num;++i)
{
p->vexs[i]=i;
}
for(int i=0;i<p->arcs_num;++i)
{
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
p->arcs[i].id=a;
p->arcs[i].vi=b;
p->arcs[i].vj=c;
p->arcs[i].weight=d;
}
return p;
}
Arcs arr[n0];
int weight=0;
int vexn=1;
void Prim(AMGraph *p)
{
int m=p->vexs_num;
int vex[m];
vex[0]=0;
while(1)
{
int min=INFINITY;
Arcs* arc=NULL;
int v=-1;
for(int j=0;j<vexn;j++)
{
for(int i=0;i<p->arcs_num;++i)
{
int sign=0;
for(int k=0;k<vexn-1;++k)
{
if(arr[k].id==p->arcs[i].id) sign=1;
}
if(sign) continue;
if(p->arcs[i].vi==vex[j] || p->arcs[i].vj==vex[j])
{
if(p->arcs[i].weight<min)
{
int sign=0;
if(p->arcs[i].vi==vex[j])
for(int k=0;k<vexn;++k)
if(p->arcs[i].vj==vex[k]) sign=1;
if(p->arcs[i].vj==vex[j])
for(int k=0;k<vexn;++k)
if(p->arcs[i].vi==vex[k]) sign=1;
if(sign) continue;
min=p->arcs[i].weight;
arc=&(p->arcs[i]);
if(p->arcs[i].vi==vex[j]) v=p->arcs[i].vj;
else v=p->arcs[i].vi;
}
}
}
}
if(arc!=NULL && v!=-1)
{
arr[vexn-1]=*arc;
vex[vexn]=v;
weight+=arc->weight;
++vexn;
}
if(vexn==p->vexs_num) break;
}
}
int main()
{
AMGraph *p=CreateGraph();
Prim(p);
printf("%d\n",weight);
for(int i=0;i<vexn-2;++i)
for(int j=0;j<vexn-2-i;++j)
if(arr[j].id>arr[j+1].id)
{
Arcs t=arr[j+1];
arr[j+1]=arr[j];
arr[j]=t;
}
for(int i=0;i<vexn-1;++i)
{
if(i==0) printf("%d",arr[i].id);
else printf(" %d",arr[i].id);
}
return 0;
}
测试结果: