現有村落間道路的統計資料表中,列出了有可能建設成標準公路的若干條道路的成本,求使每個村落都有公路連通所需要的最低成本。
輸入格式:
輸入資料報括城鎮數目正整數n(≤1000)和候選道路數目m(≤3n);隨後的m行對應m條道路,每行給出3個正整數,分別是該條道路直接連通的兩個城鎮的編號以及該道路改建的預算成本。為簡單起見,城鎮從1到n編號。
輸出格式:
輸出村村通需要的最低成本。如果輸入資料不足以保證暢通,則輸出−1,表示需要建設更多公路。
輸入樣例:
6 151 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
輸出樣例:
思路
顯然這是一道經典的prim演算法的題目,注意prim演算法和dijkstra演算法雖然有相似之處,但是這兩個演算法並不等價。
prim演算法強調的是每次都選擇與「當前樹」最短距離的頂點,選擇後要更新其他點的距離,不斷地讓「當前樹」長大;
dijkstra演算法是每次都選擇距離某一源點s最短距離的頂點, 選擇後要更新其他點的距離,直到把所有點都納入進去;
比如在以上的圖中,prim演算法將會選擇cd邊,而dijkstra演算法將會選擇ad邊(如果以a為源點)
在實際解決這道題的時候,需要注意以下幾點:
本題的核心演算法是prim演算法,在執行prim演算法之前,需要定義兩個圖,乙個圖用來儲存題目給的資料,另乙個圖來儲存應該選擇的邊(結合題意就是,應該修的道路)。當然教材上是用兩種不同的圖型別,這完全沒有必要,完全可以都用鄰接表的資料型別來儲存graph圖和mst圖。
因為頂點的編號從1開始,所以在insertedge之前需要進行e->v1–,e->v2–的操作。
在prim演算法中,兩個圖都用鄰接表型別儲存,會使**更簡潔。prim演算法中需要有dist陣列、parent陣列,每次都選擇dist陣列中非零最小值的頂點v。接著用頂點v和它的父結點parent[v],完成對mst插入正確邊的操作。
mst插入邊完成後,對dist陣列和parent陣列進行更新,迴圈下去,直到所有頂點都納入mst中。
當然需要乙個totalweight的變數始終記錄著選中的邊的和。
實現
#include
#include
#define maxn 1000
#define infinity 100000
#define error -1
typedef
int vertex;
typedef
int weighttype;
typedef
struct adjvnode *ptrtoadjvnode;
struct adjvnode
;typedef
struct vnode
adjlist[maxn]
;typedef
struct gnode *lgraph;
struct gnode
;typedef
struct enode *ptrtoenode;
typedef ptrtoenode edge;
struct enode
;lgraph creategraph
(int vertexnum)
return graph;
}void
insertedge
(lgraph graph, edge e)
lgraph buildgraph
(int vertexnum,
int edgenum)
}return graph;
}vertex findmindist
(lgraph graph, weighttype *dist)}if
(mindist == infinity)
return error;
else
return minv;
}weighttype prim
(lgraph graph, lgraph mst)
ptrtoadjvnode tmpe = graph->g[0]
.firstedge;
while
(tmpe !=
null
)int vcount =0;
dist[0]
=0; parent[0]
=-1;
vcount++
; edge e =
(edge)
malloc
(sizeof
(struct enode));
weighttype totalweight =0;
while(1
) tmpe = tmpe->next;}}
if(vcount < graph->nv)
totalweight = error;
return totalweight;
}int
main()
PTA 資料結構與演算法 7 10 公路村村通
如有不對,不吝賜教 進入正題 現有村落間道路的統計資料表中,列出了有可能建設成標準公路的若干條道路的成本,求使每個村落都有公路連通所需要的最低成本。輸入格式 輸入資料報括城鎮數目正整數n 1000 和候選道路數目m 3n 隨後的m行對應m條道路,每行給出3個正整數,分別是該條道路直接連通的兩個城鎮的...
最小生成樹 案例6 1 7 公路村村通
題目鏈結 思路 最小生成樹問題,我們直接利用kruskal演算法。即將所有邊按照權重從小到大排列,每次挑選其中權重最小的邊生成樹,並且每次挑選時要篩去選擇該邊會形成迴路的邊,利用並查集即可,若在並查集中兩點同根,即兩點連通,則選擇連線兩點的邊會形成迴路.include include include...
資料結構PTA 案例6 1 5 旅遊規劃
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度 以及該公路要收取的過路費。現在需要你寫乙個程式,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。如果有若干條路徑都是最短的,那麼需要輸出最便宜的一條路徑。輸入格式 輸入說明 輸入資料的第1行給出4個正整數n m s d,其中n 2 n 50...