最小生成樹的算法

今天寫了一個最小生成樹的算法,也是爲了準備藍橋杯。題解再說,先專門討論算法。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 }
View Code
相關文章
相關標籤/搜索