图论——最小生成树

Posted -iris-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论——最小生成树相关的知识,希望对你有一定的参考价值。

最小生成树算法

是图论的一种算法

 

用N个点用N-1条边连成一棵树

所以在图中选N个点与N-1条边

使在所有方案中和最小

 

1°:

Prim算法

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew= {x},其中x为集合V中的任一节点(起始点),Enew= {},为空;
3).重复下列操作,直到Vnew= V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
 
这个算法你就当个笑话看看吧,反正也不常用
 

Kruskal算法

  假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
 
然后上代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 int f[300000];
 8 
 9 struct point{
10     int x;
11     int y;
12     int z;
13 }edge[300000];
14 
15 bool cmp(point a,point b)
16 {
17     return a.z<b.z;
18 } 
19 
20 inline int Find(int a)
21 {
22     if(f[a]!=a) f[a]=Find(f[a]);
23     return f[a];
24 }
25 
26 inline void join(int a,int b)
27 {
28     int fa=Find(a);
29     int fb=Find(b);
30     if(fa!=fb) f[fa]=fb;
31 }
32 
33 int main(void)
34 {
35     
36     int n,m;
37     
38     scanf("%d%d",&n,&m);
39     
40     for(register int i=1;i<=m;i++)
41         scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);
42     
43      sort(edge+1,edge+1+m,cmp);
44     
45      for(register int i=1;i<=n;i++)
46         f[i]=i;
47     
48     int tot=0;
49     
50     int k=0;
51 
52     for(int i=1;i<=m;i++)
53     {
54     
55         if(Find(edge[i].x) != Find(edge[i].y))
56         {
57             join(edge[i].x,edge[i].y);
58             tot+=edge[i].z;
59             k++;
60         }
61         if(k==n-1) break;
62 
63     }
64     
65     printf("%d",tot);
66 }

 

 

克鲁斯卡尔算法使用的了

并查集思想

快速排序

优先连权值更大的边

复杂度为 O(mlogm)

 

而普利姆算法则采用dp思想,复杂度为 O(N^2),优化后达到 O(mlogn)

 

综合比对来看

1°Prim在稠密图中比Kruskal优,稀疏图劣

2°Prim在任何情况下均有令人满意的时间复杂度,代价就是空间复杂度极高,并且代码极其恶心

但是时间复杂度不能说明一个算法的优劣性质

 

所以考试,你想用啥就用啥。

以上是关于图论——最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

图论之最小生成树最小生成树专题

图论——迪杰斯特拉算法和最小生成树

图论 最小生成树

怎么求最小生成树 (离散数学 图论)

浅谈图论——最小生成树

图论讲解——最小生成树