贪心算法之prim算法的证明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法之prim算法的证明相关的知识,希望对你有一定的参考价值。

参考技术A 令 为一个带权连通图,T为G的一生成树。对任一不在T中的边 ,如果将 加入T中, 产生一条回路,且 是回路中权值最大的边,那么树T具有MST性质。
引理1:如果生成树 都具有MST性质,那他们的总代价相同。
proof (采用归纳法):假设 有k条边不相同,下面对k进行归纳:

引理2:生成树T为最小生成树 T具有MST性质
proof:

设边 加入T以后产生回路,且回路中存在边 ,则我们将 删除,得到新的生成树 ,则有 , 这与T是最小生成树矛盾,因此 是回路中权重最大的边。

不妨设 是最小生成树,由必要性证明知 有MST性质,再由引理1知道 和 总代价相同,则 也是最小生成树。

proof(反证):
假设构造的生成树为 ,且不具有MST性质,不妨设 E(G)-E(T) ,即不在T中的、最小的一条边,将 加入T中形成一个环,由于T不具有MST性质,则环中一定存在一条边 ,且 ,接下来分情况讨论:

综上所述,prim算法产生的生成树具有MST性质。

贪心算法之Prim

Prim与Dijistra算法有异曲同工之妙,只不过Dijistra是求最短路径,每次添加到集合中的是到固定起始点的最短距离,而Prim是求最小生成树,是整个图所有权重的最小和,每次添加到集合中的是到整个集合最短距离的点。

Prim算法具体如下所示:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 #define INF 1e7
 6 #define MAXNODE 100
 7 
 8 bool flag[MAXNODE];
 9 int closest[MAXNODE];
10 int lowcost[MAXNODE];
11 
12 void prim(int n, int u0, int map[MAXNODE][MAXNODE]);
13 
14 int main() {
15     int n, m, u, v, w;
16     cout << "请输入节点数n和边数m:";
17     cin >> n >> m;
18     cout << "请输入节点边的权值:";
19     int map[MAXNODE][MAXNODE];
20     for (int i = 0; i < n; i++) {
21         for (int j = 0; j < n; j++)
22             map[i][j] = INF;
23     }
24     for (int i = 0; i < m; i++) {
25         cin >> u >> v >> w;
26         map[u][v] = map[v][u] = min(w, map[u][v]);
27     }
28     cout << "请输入开始点:";
29     int u0;
30     cin >> u0;
31     prim(n, u0, map);
32     int sum = 0;
33     for(int i = 0; i < n; i++){
34         sum += lowcost[i];
35     }
36     cout<<sum;
37     return 0;
38 }
39 
40 void prim(int n, int u0, int map[MAXNODE][MAXNODE]) {
41     //初始化
42     flag[u0] = true;
43     for (int i = 0; i < n; i++) {
44         if (i != u0) {
45             lowcost[i] = map[u0][i];
46             closest[i] = u0;
47         } else {
48             lowcost[i] = 0;
49         }
50     }
51     //开始找最近点
52     for (int i = 0; i < n-1; i++) {
53         int m = INF;
54         int temp = u0;
55         for(int j = 0; j < n; j++) {
56             if (flag[j] == false && lowcost[j] < m){
57                 m = lowcost[j];
58                 temp = j;
59             }
60         }
61         if(temp == u0){
62             break;
63         }
64         flag[temp] = true;
65         for(int j = 0; j < n; j++){
66             if(flag[j] == false && lowcost[j] > map[j][temp]){
67                 lowcost[j] = map[j][temp];
68                 closest[j] = temp;
69             }
70         }
71     }
72 }

 

以上是关于贪心算法之prim算法的证明的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法之最小生成树(Prim和kruskal算法)

算法笔记-贪心算法

图--05---贪心算法Prim算法kruskal算法

贪心算法-区间调度问题解之证明

贪心思想

About: 算法之贪心算法