前言

说到最小生成树(Minimum Spanning Tree),首先要对以下的图论概念有所了解。

图(Graph)是表示物件与物件之间的关系的数学对象,是图论的基本研究对象。图的定义方式有两种,其一是二元组定义。图G是一个有序二元组(V,E),其中V称为顶集(Vertices Set),E称为边集(Edges set),E与V不相交。它们亦可写成V(G)和E(G)。

边的方向

边是有方向的,单方向(如只允许从点a到达点b)的边称为单向边有向边;允许双方互达的边称为双向边无向边。包含单向边的图称为单向图,不包含单向边的称为无向图

带权图

图上的边或者点都可以带有权值,带权值的图就称为带权图。

子图

任取图G的若干点,以及这些点在G中存在的若干边构成的集合称为G的子图。

连通图

如果无向图G的任意点都可以直接或间接地到达其余所有点,那么G就称为连通图。

树是一种特殊的图,树上的所有点与其他点之间有且仅有一条直接或间接路径。性质:|V|=|E|+1。

生成树

如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树。显然对于同一个图,生成树并不唯一。

最小生成树

定义

图G的最小生成树(假设存在)是边权和最小的生成树。

算法

Prim和Kruskal

Prim

Prim又称加点法。

步骤

•在G中任意选取一个结点v_1,置V={v_1},E=∅,k=1

•在V-V中选取与某个v_i ∈V邻接的结点v_j ,使得边(v_i , v_j)权值最小,置V=V∪{v_j },E=E∪{(v_i ,v_j )},k=k+1

•重复第二步,直到k=|V|

复杂度

$$
O(\mid V\mid^2)
$$

模板

// cost 0~n-1
// 不连通 return -1
const int INF = 0x3f3f3f3f;
const int MAXN = 110;
bool vis[MAXN];
int lowc[MAXN];

int Prim(int cost[][MAXN], int n) {
    int ans = 0;
    memset(vis, false, sizeof(vis));
    vis[0] = true;
    for (int i = 1; i < n; i++)
        lowc[i] = cost[0][1];
    for (int i = 1; i < n; i++) {
        int minc = INF;
        int p = -1;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && minc > lowc[j]) {
                minc = lowc[j];
                p = j;
            }
        }
        if (minc == INF) {
            return -1;
        }
        ans += minc;
        vis[p] = true;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && lowc[j] > cost [p][j]) {
                lowc[j] = cost[p][j];
            }
        }
    }
    return ans;
}

Kruskal

Kruskal又称加边法。

步骤

•在G中选取最小权边e_1,置i=1

•当i=n-1时,结束,否则进行下一步

•设已选取的边为e_1 ,e_2,……, e_i ,在G中选取不同于以上的边e_i+1,使得{e_1 ,e_2,……, e_i , e_i+1}中无回路且e_i+1是满足此条件的最小权边。

•置i=i+1,转第二步

复杂度

$$
O(\mid E\mid \log \mid E \mid)
$$

模板

const int MAXM = 10000; // 边
const int MAXN = 110; // 点

int F[MAXN]; // 并查集

struct Edge {
    int u, v, w; // 起点、终点、权值
}edge[MAXN];

int tol; // 边数,加边算法,初始为零

void AddEdge(int u, int v, int w) {
    edge[tol].u = u;
    edge[tol].v = v;
    edge[tol++].w = w;
}

bool CMP(Edge a, Edge b) {
    return a.w < b.w;
}

int Find(int x) {
    return x == F[x] ? x : F[x] = Find(x);
}

// n 为图的点总数
int Kruskal(int n) {
    memset(F, -1, sizeof(F));
    sort(edge, edge + tol, CMP);
    int cnt = 0, ans = 0;
    for (int i = 0; i < tol; i++) {
        int u = edge[i].u;
        int v = edge[i].v;
        int w = edge[i].w;
        int t1 = Find(u);
        int t2 = Find(v);
        if (t1 != t2) {
            ans += w;
            F[t1] = t2;
            cnt++;
        }
        if (cnt == n - 1) {
            break;
        }
    }
    return cnt < n - 1 ? -1 : ans;
}

Minimum Spanning Tree的更多相关文章

  1. 【HDU 4408】Minimum Spanning Tree(最小生成树计数)

    Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...

  2. 数据结构与算法分析–Minimum Spanning Tree(最小生成树)

    给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...

  3. Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST

    E. Minimum spanning tree for each edge   Connected undirected weighted graph without self-loops and ...

  4. CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  5. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  6. MST(Kruskal’s Minimum Spanning Tree Algorithm)

    You may refer to the main idea of MST in graph theory. http://en.wikipedia.org/wiki/Minimum_spanning ...

  7. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

  9. Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  10. 说说最小生成树(Minimum Spanning Tree)

    minimum spanning tree(MST) 最小生成树是连通无向带权图的一个子图,要求 能够连接图中的所有顶点.无环.路径的权重和为所有路径中最小的. graph-cut 对图的一个切割或者 ...

随机推荐

  1. WPF 使用字体引发的 CLR20r3 问题排查

    开发机器上运行完好,拷贝置目标机器上出现此问题 问题排查: 计算机-->管理-->事件查看器--->windows日志-->应用程序 Application Error  看不 ...

  2. Redis 一些高级用法

    延迟消息队列 利用 expire keyspace notification Redis 过期时,会向特定的消息队列发送消息,监听该消息队列 在 redis.conf 修改 notify-keyspa ...

  3. 【WPF】右下角弹出自定义通知样式(Notification)——简单教程

    原文:[WPF]右下角弹出自定义通知样式(Notification)--简单教程 1.先看效果 2.实现 1.主界面是MainWindow 上面就只摆放一个Button即可.在Button的点击事件中 ...

  4. Image Captioning 经典论文合辑

    Image Caption: Automatically describing the content of an image domain:CV+NLP Category:(by myself, y ...

  5. Win7和Vista的安全机制对于应用程序读取配置文件相关操作的影响(虚拟重定向技术)

    今天构造了一个新版本的XXXX软件,并且在纯净的系统下进行了较为全面的测试.测试中也发现了一些问题.其中包括在Win7测试时程序竟然在另一个目录中创建了文件夹和配置文件,并且进行相关读取操作,却并没有 ...

  6. Debug监视器(监视运行期程序通过API函数OutputDebugString输出的字符串)

    http://download.csdn.net/detail/zswang/207199

  7. windows下进程间通信的(13种方法)

    转自:http://blog.csdn.NET/shiqz/article/details/5862936 摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进 ...

  8. 关于Qt 5-MSVC 2015 64位在 win7 64位系统debug程序崩溃的问题

     关于Qt 5-MSVC 2015 64位在 win7 64位系统debug程序崩溃的问题 在win7 64位系统安装VC2015的编译器,并安装了 Qt 5.6 -5.7 VC2015 64位版本测 ...

  9. SYN2136型 北斗NTP网络时间服务器

    SYN2136型  北斗NTP网络时间服务器 北斗NTP网络时间服务器时间服务器使用说明视频链接: http://www.syn029.com/h-pd-109-0_310_36_-1.html 请将 ...

  10. STL-空间配置器、迭代器、traits编程技巧

    目录 内存分配和释放 对象的构造和析构 traits要解决的问题 内嵌类别声明解决非指针迭代器的情况 使用模板特例化解决普通指针的情况 迭代器相应类别 内存分配和释放 STL中有两个分配器,一级分配器 ...