今天寫了一個最小生成樹的算法,也是爲了準備藍橋杯。題解再說,先專門討論算法。html
最小生成樹的算法原理我一直都知道,就是代碼一直不會寫。簡單說一下原理好了。一個無向無環圖,每條邊上有相應的權值,找到權值的和最小的生成樹就是最小生成樹。首先將全部的點分爲兩個集合U,V。其中U是已經找到對應邊的點。每次尋找U到V的最短邊,而且把這條邊在V中的端點加入U。循環下去直到全部的點都被找到。ios
靈感來源於http://blog.chinaunix.net/uid-25324849-id-2182922.html算法
下面是代碼,註釋很清楚了(不連通的點距離是無窮大,本身到本身也是無窮大)數組
1 #include<iostream> 2 #include<stack> 3 #include<stdio.h> 4 #include<string.h> 5 using namespace std; 6 const int in = 1000; 7 int main() 8 { 9 int map[5][5] = {{in,30,in,in,in},{30,in,40,40,70},{in,40,in,60,62},{in,40,60,in,60},{in,70,62,60,in}}; 10 int cost[5];//當前點集合內的點到其餘點的最短距離 11 int point[5];//在集合內的邊(i,point[i]) 12 bool visit[5];//該點在不在集合內 13 int father[5];//好像沒什麼用 14 int i; 15 //先將第一個點加入集合內而且給數組們賦值 16 for(i = 0;i < 5;i++) 17 { 18 cost[i] = map[0][i]; 19 point[i] = 0; 20 visit[i] = false; 21 father[i] = 0; 22 } 23 visit[0] = true; 24 int k; 25 //有n個頂點就有n-1條邊,進行n-1次循環求出這些邊 26 for(k = 1;k < 5;k++) 27 { 28 int j = 0; 29 int min = in; 30 //找出不在集合內的與集合內的點距離最短的點 31 for(i = 0;i < 5;i++) 32 { 33 34 if(!visit[i] && min > cost[i]){min = cost[i];j = i;} 35 } 36 //將這個點加入集合 37 visit[j] = true; 38 father[j] = point[j]; 39 //更新數組們 40 for(i = 0;i < 5;i++) 41 { 42 //對於還不在集合內點,若是與新加入的點的距離小於原來的距離就改變cost數組, 43 //而且將該點的邊的另外一端改成新加入的點 44 //i是不在集合裏的點,j是剛纔加入的點 45 if(!visit[i] && cost[i]>map[j][i]){cost[i] = map[j][i];point[i] = j;} 46 } 47 cout<<j<<" "<<point[j]<<endl;//打印出這個新加入的邊 48 } 49 int sum = 0; 50 for(i = 1;i < 5;i++) 51 { 52 sum += map[i][point[i]]; 53 } 54 cout<<sum;//最小生成樹的權值之和 55 return 0; 56 }