码迷,mamicode.com
首页 > 其他好文 > 详细

最少布线(图)

时间:2019-02-01 18:03:00      阅读:468      评论:0      收藏:0      [点我收藏+]

标签:问题   自然数   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

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!