日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

中国大学MOOC-数据结构基础习题集、06-3、公路村村通

發(fā)布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中国大学MOOC-数据结构基础习题集、06-3、公路村村通 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:http://www.patest.cn/contests/mooc-ds/06-3

題目分析:典型最小生成樹問題,且只需輸出樹各邊的權(quán)值之和出來就可以了。博主這里用的是Prim算法。

特別說明:

  1. 用鄰接矩陣表示圖比較容易。保存路徑長度就可以了。因為強調(diào)了數(shù)組下標(biāo)從1開始,因此在輸入完n和m時,先執(zhí)行一步n++,方便以后為數(shù)組申請空間。

  2. 二維數(shù)組的動態(tài)申請及初始化,不推薦大家#define一個較大的數(shù),然后直接int a[MAX][MAX],這樣做是十分不負(fù)責(zé)的,十分浪費空間。如果不會的同學(xué),可以參見如下方法:

1 // 用鄰接矩陣存儲圖 2 int **data = new int*[n]; 3 for(int i=0; i<n+1; i++) 4 { 5 data[i] = new int[n]; 6 } 7 // 鄰接矩陣初始化 8 for(int i=0; i<n; i++) 9 { 10 for(int j=0; j<n; j++) 11 { 12 data[i][j] = MAXNUM; 13 } 14 }

  3. 求“尚未收集”的dist值最小的函數(shù),參數(shù)是dist,collected標(biāo)記是否被收集,及數(shù)組的長度n。注意數(shù)組下標(biāo)從1開始:

1 int minDist(int dist[], bool collected[], int n) 2 { 3 int mindist = MAXNUM; 4 int icount = NOTEXIST; 5 for(int i=1; i<n ; i++) 6 { 7 if(dist[i] < mindist && collected[i] == false) 8 { 9 icount = i; 10 mindist = dist[i]; 11 } 12 } 13 return icount; 14 }

  4. 用#define定義無窮大(100000000)和不存在(-1),避免程序中出現(xiàn)魔數(shù),也方便修改。

1 #define MAXNUM 10000000 2 #define NOTEXIST -1

  5. 可以用fill函數(shù),對一個數(shù)組進(jìn)行快速初始化,避免寫for循環(huán)。方法如下:

1 fill(a, a+aLen, 100); // 數(shù)組a長度為aLen,用100填滿整個數(shù)組

代碼分析:

  普利姆算法:24~71(其中parent數(shù)組不設(shè)定也可以,這里并沒有要求表示樹的結(jié)構(gòu))

  主函數(shù):72~100(注意輸入圖的數(shù)據(jù)時,注意是圖是無向圖,也就是雙向圖)

1 #include <iostream> 2 #include <stack> 3 4 #define MAXNUM 10000000 5 #define NOTEXIST -1 6 7 using namespace std; 8 9 int minDist(int dist[], bool collected[], int n) 10 { 11 int mindist = MAXNUM; 12 int icount = NOTEXIST; 13 for(int i=1; i<n ; i++) 14 { 15 if(dist[i] < mindist && collected[i] == false) 16 { 17 icount = i; 18 mindist = dist[i]; 19 } 20 } 21 return icount; 22 } 23 24 int Prim(int *data[], int n, int m) 25 { 26 // 集合: 用來存儲收集到的結(jié)點 27 stack<int> MST; 28 MST.push(0); 29 // dist: 記錄長度 30 int *dist = new int[n]; 31 fill(dist, dist+n, MAXNUM); 32 dist[1] = 0; 33 // collected: 標(biāo)記是否被訪問 34 bool *collected = new bool[n]; 35 fill(collected, collected+n, false); 36 // parent: 記錄樹的結(jié)構(gòu) 37 int *parent = new int[n]; 38 fill(parent, parent+n, NOTEXIST); 39 // output: 最終結(jié)果 40 int output = 0; 41 while (1) 42 { 43 int V = minDist(dist, collected, n); 44 if (V == NOTEXIST) 45 break; 46 MST.push(V); 47 output += dist[V]; 48 dist[V] = 0; 49 collected[V] = true; 50 for(int W=1; W<n; W++) 51 { 52 if(data[V][W] != MAXNUM // 如果W是V的鄰接點 53 && collected[W] == false // 如果W沒有被訪問 54 && data[V][W] < dist[W]) 55 { 56 dist[W] = data[V][W]; 57 parent[W] = V; 58 } 59 } 60 } 61 if(MST.size() != n) 62 return NOTEXIST; 63 else 64 return output; 65 } 66 /* 67 dist[V] = E(s,V)或 正無窮 68 parent[s] = -1(代表根結(jié)點) 69 T = O( |V|2 ) 70 */ 71 72 int main() 73 { 74 int n, m; 75 cin >> n >> m; 76 n++; 77 // 用鄰接矩陣存儲圖 78 int **data = new int*[n]; 79 for(int i=0; i<n+1; i++) 80 { 81 data[i] = new int[n]; 82 } 83 // 鄰接矩陣初始化 84 for(int i=0; i<n; i++) 85 { 86 for(int j=0; j<n; j++) 87 { 88 data[i][j] = MAXNUM; 89 } 90 } 91 for(int i=0; i<m; i++) 92 { 93 int a, b, c; 94 cin >> a >> b >> c; 95 data[a][b] = c; 96 data[b][a] = c; 97 } 98 cout << Prim(data, n, m) << endl; 99 return 0; 100 }

AC成果:

?

轉(zhuǎn)載于:https://www.cnblogs.com/clevercong/p/4215966.html

總結(jié)

以上是生活随笔為你收集整理的中国大学MOOC-数据结构基础习题集、06-3、公路村村通的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。