标签:问题 自然数 line 题解 while 权重 实现 scanf print
【问题描述】
网络中心计划要给相关建筑物间铺设光缆进行网络连通,请给出用料最少的铺设方案。
编写程序输入一个办公区域分布图及建筑物之间的距离,计算出用料最少的铺设方案(只有一组最优解,不用考虑多组解)。要求采用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。其对应的最小生成树如下:
【题解】
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define MAXLINE 500 5 6 typedef struct Routes 7 { 8 int num; 9 int vera; 10 int verb; 11 int weight; 12 }Routes; 13 14 Routes road[MAXLINE]; 15 int pre[MAXLINE]; 16 int ans[MAXLINE]; 17 int use=0; 18 19 void SelectionSort_Road(int num,Routes r[]); 20 void SelectionSort(int num,int a[]); 21 int find(int root); 22 int kruskal(int RouteNum); 23 24 int main(void) 25 { 26 int VertexNum,RouteNum,MinUse; 27 int i; 28 29 scanf("%d %d",&VertexNum,&RouteNum); 30 for(i=0;i<MAXLINE;i++) 31 pre[i]=i; 32 for(i=0;i<RouteNum;i++) 33 scanf("%d %d %d %d",&road[i].num,&road[i].vera,&road[i].verb,&road[i].weight); 34 35 MinUse=kruskal(RouteNum); 36 SelectionSort(use,ans); 37 38 printf("%d\n",MinUse); 39 for(i=0;i<use-1;i++) 40 printf("%d ",ans[i]); 41 printf("%d\n",ans[i]); 42 43 return 0; 44 } 45 void SelectionSort_Road(int num,Routes r[]) 46 { 47 int i,j,min; 48 Routes temp; 49 50 for(i=0;i<num-1;i++) 51 { 52 min=i; 53 for(j=i+1;j<num;j++) 54 if(r[j].weight<r[min].weight) 55 min=j; 56 if(min!=i) 57 { 58 temp=r[min]; 59 r[min]=r[i]; 60 r[i]=temp; 61 } 62 } 63 return; 64 } 65 void SelectionSort(int num,int a[]) 66 { 67 int i,j,min,temp; 68 69 for(i=0;i<num-1;i++) 70 { 71 min=i; 72 for(j=i+1;j<num;j++) 73 if(a[j]<a[min]) 74 min=j; 75 if(min!=i) 76 { 77 temp=a[min]; 78 a[min]=a[i]; 79 a[i]=temp; 80 } 81 } 82 return; 83 } 84 int find(int root) 85 { 86 int child,temp; 87 88 child=root; 89 while(root!=pre[root]) 90 root=pre[root]; 91 while(child!=root) 92 { 93 temp=pre[child]; 94 pre[child]=root; 95 child=temp; 96 } 97 98 return root; 99 } 100 int kruskal(int RouteNum) 101 { 102 int i,j; 103 int sum=0; 104 105 SelectionSort_Road(RouteNum,road); 106 107 for(i=0,j=0;i<RouteNum;i++) 108 { 109 int roota=find(road[i].vera); 110 int rootb=find(road[i].verb); 111 112 if(roota!=rootb) 113 { 114 sum+=road[i].weight; 115 ans[j++]=road[i].num; 116 use++; 117 pre[roota]=rootb; 118 } 119 } 120 return sum; 121 }
标签:问题 自然数 line 题解 while 权重 实现 scanf print
原文地址:https://www.cnblogs.com/tuoniao/p/10346411.html