1. 程式人生 > >最少布線(圖)

最少布線(圖)

不用 編寫 pan 輸出 can turn 建築 說明 ota

【問題描述】

網絡中心計劃要給相關建築物間鋪設光纜進行網絡連通,請給出用料最少的鋪設方案。

編寫程序輸入一個辦公區域分布圖及建築物之間的距離,計算出用料最少的鋪設方案(只有一組最優解,不用考慮多組解)。要求采用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 }

最少布線(圖)