MST — Kruskal's algorithm

算法简介

  Kruskal算法可用来求解MST(最小生成树)问题,还可以作为迷宫生成算法等。

算法分析

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

  时间复杂度 $ O(ElgV) $

  空间复杂度 $ 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; // w:权重
		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](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)

    2.[Maze generation algorithm - wikipedia](https://en.wikipedia.org/wiki/Maze_generation_algorithm)

    3.CLRS $ P_{366} $ 伪代码

猜你喜欢

转载自www.cnblogs.com/darkchii/p/9556122.html
MST