資料結構實驗之圖論六:村村通公路【Prim演算法】(SDUT 3362)
阿新 • • 發佈:2018-12-11
題解:選點,選最小權的邊,更新點權。可以手動自行找一遍怎麼找到這個最小的生成樹,隨便選一個點放入我們選的集合中,然後看和這個點相連的點中,與那個點相連的那條邊權值是最小的,選擇之後,把相連的這個點一起放入集合中,這樣的話集合中就多了一點,現在要找和這兩個點都相連的點中,那個邊的權最小,直到全部的點都在集合中就完成了。
#include <iostream> #include <bits/stdc++.h> using namespace std; int inf = 0x3fffff; int gra[1005][1005]; int vis[1005]; int dist[1005]; void prim(int n) { memset(vis,0,sizeof(vis)); for(int i = 0; i <= n; i ++) dist[i] = gra[1][i]; int Min = inf, v, flag = 1; for(int i = 1; i <= n; i ++) { Min = inf; for(int j = 1; j <= n; j ++) { if(!vis[j] && dist[j] < Min){ Min = dist[j]; v = j; } } if(Min == inf) {flag = 0;break;} vis[v] = 1; for(int j = 1; j <= n; j ++) { if(!vis[j] && dist[j] > gra[v][j]){ dist[j] = gra[v][j]; } } } int ans = 0; for(int i = 1; i <= n;i ++) { ans += dist[i]; } if(flag)printf("%d\n",ans); else printf("-1\n"); } int main() { int n,m,u,v,w; while(~scanf("%d%d",&n,&m)){ for(int i = 0; i<= n; i ++) { for(int j = 0; j <= n; j ++) { if(i == j) gra[i][j] = 0; else gra[i][j] = inf; } } for(int i = 0; i < m; i ++) { scanf("%d%d%d",&u,&v,&w); gra[u][v] = gra[v][u] = w; } prim(n); } return 0; }