7-10 公路村村通(30 分)
現有村落間道路的統計數據表中,列出了有可能建設成標准公路的若干條道路的成本,求使每個村落都有公路連通所需要的最低成本。
輸入格式:
輸入數據包括城鎮數目正整數N(≤1000)和候選道路數目M(≤3N);隨后的M行對應M條道路,每行給出3個正整數,分別是該條道路直接連通的兩個城鎮的編號以及該道路改建的預算成本。為簡單起見,城鎮從1到N編號。
輸出格式:
輸出村村通需要的最低成本。如果輸入數據不足以保證暢通,則輸出−1,表示需要建設更多公路。
輸入樣例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
輸出樣例:
12
解題思路:1、這道題一開始走偏了想直接同floyd算法求出最短路徑然后相加了
最小生成樹能夠保證整個拓撲圖的所有路徑之和最小,但不能保證任意兩點之間是最短路徑。
最短路徑是從一點出發,到達目的地的路徑最小。
2、理清楚了最小生成樹與最短路徑之間的區別以后就很容易想到用最小生成樹算法了,這里選用的是Prim算法
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define MAXVEX 1003 5 #define INFINITY 65535 6 7 void CreateGraph( ); 8 int Prim(); 9 10 int G[MAXVEX][MAXVEX],Nv,Ne; 11 12 int main() 13 { 14 int f = 0; 15 16 scanf("%d %d",&Nv,&Ne); 17 CreateGraph(); 18 f =Prim(); 19 printf("%d",f); 20 21 return 0; 22 } 23 24 void CreateGraph() 25 { 26 //用鄰接矩陣表示圖 27 int i,j; 28 int v1,v2,w; 29 30 for( i=1; i<=Nv; i++) 31 { 32 for( j=1; j<=Nv; j++) 33 { 34 G[i][j] = INFINITY; //初始化 35 } 36 } 37 38 for( i=0; i<Ne; i++) //注意這里是讀入邊 39 { 40 scanf("%d %d %d",&v1,&v2,&w); 41 G[v1][v2] = w; //讀入權值 42 G[v2][v1]= G[v1][v2]; //無向圖對稱 43 } 44 } 45 46 47 int Prim() 48 { 49 int min; 50 int i,j,k; 51 int lowcost[MAXVEX]; 52 int cost =0; 53 54 55 lowcost[1] = 0; //初始化第一個權值為0,即v0加入生成樹 56 57 for( i=2; i<=Nv; i++) 58 { 59 lowcost[i] = G[1][i]; 60 } 61 62 for( i=2; i<=Nv; i++) 63 { 64 min = INFINITY; 65 j = 1; 66 k = 0; 67 while( j<=Nv ) 68 { 69 if( lowcost[j]!=0 && lowcost[j]<min) 70 { 71 min = lowcost[j]; 72 k = j; //將當前最小值的下標存入k 73 } 74 j++; 75 } 76 77 if(k==0) 78 { 79 return -1; //不連通 80 } 81 cost += min; 82 lowcost[k] = 0; //將當前頂點設置為0,表示此結點已經完成任務 83 84 for( j=2; j<=Nv; j++) 85 { 86 if( lowcost[j]!=0 && G[k][j]<lowcost[j]) 87 { 88 //若下標為k頂點各邊權值小於此前這些頂點未被加入生成樹的權值 89 lowcost[j] = G[k][j]; 90 } 91 } 92 93 } 94 95 return cost; 96 }
