跳过正文
  1. Docs/

Kruskal's algorithm

·456 字·1 分钟· loading · loading · · ·
Algorithms C/C++
Pacyu
作者
Pacyu
程序员
目录

Kruskal算法可用来求解最小生成树(minimum-spanning-tree, MST)问题,还可以用来生成迷宫。

算法分析
#

算法先要将 \( G(V, E) \) 的集合 \( E \) 按权重 \( \Omega \) 由小到大排序,然后还利用了不相交集中的find()(这里使用的是带路径压缩功能的) 和union()(这里函数名使用marge()) 函数,find()用于判断是否连通,如果连通则不能构成MST,反之则加入到MST的集合中,并调用union()函数将顶点连通。

时间复杂度
#

$$ O(E lg V) $$

空间复杂度
#

$$ O(V + E) $$

算法实现
#

#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int N = 10010;
int p[N];
vector<pair<int, pair<int, int>>> graph;
void init(int V, int E)
{
	for (int i = 1; i <= V; i++)
		p[i] = i;
	for (int i = 0; i < E; i++)
	{
		int w, s, e;
		cin >> w >> s >> e;
		graph.push_back(pair<int, pair<int ,int>>(w, pair<int, int>(s, e)));
	}
	sort(graph.begin(), graph.end());
	for (auto e : graph)
		cout << e.first << e.second.first << e.second.second << endl;
}
int find(int x)
{
	if (x != p[x])	p[x] = find(p[x]);
	return p[x];
}
void marge(int x, int y)
{
	int r = find(x), t = find(y);
	if (r != t)	p[r] = t;
}
vector<pair<int, int>> kruskal(int V, int E)
{
	vector<pair<int, int>> msts;
	init(V, E);
	for (vector<pair<int, pair<int, int>>>::iterator i = graph.begin(); i != graph.end(); i++)
	{
		if (find(i->second.first) != find(i->second.second))
		{
			msts.push_back(i->second);
			marge(i->second.first, i->second.second);
		}
	}
	return msts;
}
int main(int argc, char **argv)
{
	int V, E;
	cin >> V >> E;
	vector<pair<int, int>> es = kruskal(V, E);
	for (auto e : es)
		cout << e.first << "  " << e.second << endl;
	return 0;
}

参考
#

  1. Kruskal’s algorithm - wikipedia
  2. Maze generation algorithm - wikipedia
  3. CLRS \( P_{366} \) 伪代码

相关文章

Tarjan's algorithm
·950 字·2 分钟· loading · loading
Algorithms C/C++
Tarjan算法可以用来求有向图的强连通分量个数。算法由Ro
拓扑排序
·681 字·2 分钟· loading · loading
Algorithms C/C++
生活中许多实际应用都需要使用有向无环图来指明事件的优先次序。
Kosaraju's algorithm
·890 字·2 分钟· loading · loading
Algorithms C/C++
该算法可以用来求解一个有向图的强连通分量。 算法解析 # 什么是强
牛顿法(Newton's method)
·961 字·2 分钟· loading · loading
Algorithms Mathematical C/C++ Math
牛顿法也是数值分析中很常见的算法了。嘛,网上对它的各种介绍也
线段树(Segment tree)
·848 字·2 分钟· loading · loading
Algorithms C/C++
一种区间操作算法。 算法实现 # #include <iostream> #define LC(i) ((i) << 1) #define RC(i) ((i) << 1 | 1) #define M
树状数组(Fenwick tree)
·440 字·1 分钟· loading · loading
Algorithms C/C++
树状数组是一种是常用于区间操作的算法。 算法实现 # #include <iostream> #define LSB(i) (i &