最小生成树

最小生成树

大纲

  1. Kruskal算法

  2. Prim算法 and/or Dijkstra算法

最小生成树的概念

图?

由一个点集V(表示所有点)和一个边集E(表示所有边)共同构成的数据结构。V和E甚至可以是空集。

延伸:

  1. 有向图、无向图

  2. 连通图、强连通图 连通图指所有点都相连;强连通图指在有向图中,每两个点都可以互相到达($\therefore强连通图\subset连通图​$)

  3. 有向无环图(DAG)、无向连通图

  4. 重边(两个点间有两条或以上的直连边)、自环(自己指向自己的边)

  5. ...

树?

无向无环连通图。

有根树,无根树

有根树中明确指定了两个点间的父子关系,所以可以认为边是有向的(由父亲指向儿子或相反) 无根树没有明确的父子关系,指定任意一个点当做根都可以。注意当选定作为根的顶点后,父子关系就明确了,无根树就变成了有根树。

生成树?

设图中有n个顶点,选出n-1条边来构成一个树,即称为该图的生成树。

最小生成树?

在某个图的所有生成树里边权之和最小的那个。

Kruskal算法

算法流程

初始化最小生成树中没有任何边。 然后由长度从小到大依次考虑每条边: 若加入最小生成树后形成了环,则不加入;否则加入。

分析

排序过程可以直接使用STL库的sort。 算法的瓶颈在于判断环上。

解法

使用并查集维护顶点之间的连接关系。 开始时没有任何点相连,即初始化并查集。 判断环时,只需判断该边的两个顶点是否原来就相连,即是否在一个集合中。 加边时,合并集合。

证明(来自OI wiki)

思路很简单,为了造出一棵最小生成树,我们从最小边权的边开始,按边权从小到大依次加入,如果某次加边产生了环,就扔掉这条边,直到加入了 $n-1$ 条边,即形成了一棵树。

证明:使用归纳法,证明任何时候 K 算法选择的边集都被某棵 MST 所包含。

基础:对于算法刚开始时,显然成立(最小生成树存在)。

归纳:假设某时刻成立,当前边集为 $F$ ,令 $T$ 为这棵 MST,考虑下一条加入的边 $e$ 。

如果 $e$ 属于 $T$ ,那么成立。

否则, $T+e$ 一定存在一个环,考虑这个环上不属于 $F$ 的另一条边 $f$ (一定只有一条)。

首先, $f$ 的权值一定不会比 $e$ 小,不然 $f$ 会在 $e$ 之前被选取。

然后, $f$ 的权值一定不会比 $e$ 大,不然 $T+e-f$ 就是一棵比 $T$ 还优的生成树了。

所以, $T+e-f$ 包含了 $F$ ,并且也是一棵最小生成树,归纳成立。

 

【代码】:

#include<bits/stdc++.h>

using namespace std;

int n,m,k;
long long ans;
const int maxn=500005;
int fa[maxn];

struct edge   //起点,终点,权值 
{
    int x,y,z;
}a[maxn];

int find(int x)   //通过是否具有同一个父亲(是否在同一集合里)判断是否连通成环 
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}

bool cmp(edge x, edge y)  //排序 
{
    return x.z<y.z;
}

void kruskal()     //核心算法 
{
    for(int i=1;i<=n;i++) fa[i]=i;
        
    sort(a+1,a+m+1,cmp);   
    
    for(int i=1;i<=m&&k<=n-1;i++)
    {
        int f1=find(a[i].x);
        int f2=find(a[i].y);
        if(f1!=f2)
        {
            ans+=a[i].z;
            fa[f1]=f2;    //合并,连通起来
            k++;
        }
    }
    
    if(k==n-1)
      cout<<ans<<endl;
    
    else cout<<"No Solution.\n";
}

int main()
{
    scanf("%d%d",&n,&m);
    
    for(int i=1;i<=m;i++)
      scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);

    kruskal();
    
    return 0;
    
}

 

相关题目:

1.P3366 【模板】最小生成树

 

2.U69308 【常数PK系列】 #3 最小生成树

 

3.T78748 【lcez模拟赛】机场Ⅰ

  WZ的题面描述啊不行的话是输出No Solution.

 

posted @ 2019-05-06 21:09  晔子  阅读(257)  评论(0编辑  收藏  举报