[板子]最小生成树

Posted 玥~endlessly~vast

tags:

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

我们所写的最小生成树主要有两种,分别是Prime和Kluskal。

注:n表示节点数,m表示边数。

一、Prime算法

  Prime算发是一种对点的枚举算法,算法实现的实质是贪心,即每次加入的点都是离已知生成树部分最近的点,加入生成树一个新的点的同时更新还未加入的点与生成树的最小距离,所以整个时间复杂度是在O(n2)的级别,这个算法在利用堆(或优先队列)优化后可以降到O(nlogn)的级别,一般用于稠密图和完全图。

 1 struct Node{
 2     int pos,val;
 3     bool operator < (const Node & a) const   {return a.val<val;} 
 4 };
 5 priority_queue<Node> q;
 6 int dis[105];
 7 void Prime(int s)
 8     {
 9         Node x,y;
10         dis[s]=0;
11         x.val=dis[s];x.pos=s;
12         q.push(x);
13         do{
14             x=q.top();q.pop();
15             int u=x.pos;
16             sum+=dis[u];
17             dis[u]=0;
18             for(int i=1;i<=n;i++)
19                 {
20                     if(Map[u][i]+dis[u]<dis[i])
21                         {
22                             dis[i]=Map[u][i]+dis[u];
23                             y.val=dis[i];
24                             y.pos=i;
25                             q.push(y);
26                         }
27                 }
28         }while(!q.empty());
29     }

 

二、Kluskal算法

  Kluskal算法是求最小生成树的另一种算法,同样是利用了贪心的思想。我们先把所有的点看作是以自己为根的一颗树,然后再把权值最小的两个树给合并起来直到所有的点都在一棵树上的时候,即连了(n-1)条边之后。这种算法最主要的就是合并操作的实现,很容易就可以想到用并查集这种数据结构来实现,所以这整个算法的复杂度就是O(mlogm)的排序操作和O(1)的合并操作,我们可以很轻松的发现这种算法运用在稀疏图上是十分方便的。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct Edge{
 4     int fr,to,cos;
 5 }edge[10005];
 6 int fa[2005];
 7 int find(int x)
 8     {
 9         return x==fa[x]?x:fa[x]=find(fa[x]);
10     }
11 bool comp(const Edge & a,const Edge & b)
12     {
13         return a.cos<b.cos;
14     }
15 int main()
16 {
17     int n,m,p,u,v,w;
18     int sum=0,k=0;
19     scanf("%d%d",&n,&m);
20     for(int i=1;i<=n;i++)    fa[i]=i;
21     for(int i=1;i<=m;i++)
22         {
23             scanf("%d%d%d",&u,&v,&w);
24             edge[i].fr=u;
25             edge[i].to=v;
26             edge[i].cos=w;
27         }
28     sort(edge+1,edge+(m+1),comp);
29     if(k<=n-1)
30         {   
31             for(int i=1;i<=m;i++)
32                 {
33                     u=edge[i].fr;v=edge[i].to;w=edge[i].cos;
34                     u=find(u);v=find(v);
35                     if(u!=v)
36                         {
37                             fa[v]=u;
38                             sum+=w;
39                             k++;
40                             if(k==n-1)  break;
41                         }
42                 }
43         }
44     printf("%d\n",sum);
45     return 0;
46 }

 

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

(板子) 最小生成树 买礼物 luogu P1194

AcWing 1140. 最短网络最小生成树板子题

Constructing Roads POJ - 2421 最小生成树板子题

Building a Space Station POJ - 2031 三维最小生成树,其实就是板子题

Highways——最小生成树模板题(求距离)

畅通工程再续——最小生成树