2021-02-25最小生成树模板——prime算法

摘要:

最小生成树模板——prime算法
最小生成树模板——krusal算法


题目简述:

洛谷P3366最小生成树模板


算法分析:

prime算法和迪杰斯特拉算法有异曲同工之处,二者的本质都是贪心和动态规划。prime算法的思想可以概括为“逐步短接”,每一次选取当前遍历到的定点的最短的一条临边。
根据上述分析可知,由于每一次都会选取一条最短的边,因此可借鉴迪杰斯特拉算法的实现过程,采用隐式数据结构——堆,进行优化。详见代码


代码以及详细注释:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 10000000
#pragma warning(disable:4996)
using namespace std;


/*链表前向星的准备工作*/
struct edge {
    
    
	int to;
	int next;
	int w;
};

struct Node {
    
    
	int pos;  //点的编号
	int w;   //加入该点后,小增加的权值
	Node(int _pos=0, int _w=0) :pos(_pos), w(_w) {
    
    }

	bool operator()(Node& n1, Node& n2) {
    
    
		return n1.w > n2.w; //准备建立一个小根堆
	}
	friend bool operator<(Node& n1, Node& n2)
	{
    
    
		return n1.w > n2.w; //准备建立一个小根堆
	}
};


class Solution {
    
    
public:
	int cnt=0;
	vector<int> head;
	vector<edge> e;
	int n, m;
	vector<int> dis;//这里的dis数组保存的并不是从起点到某点的距离。
	//dis[i]表示的意思是加入第i个点后,最小生成树中增加的权值大小
	vector<bool> visit;
	priority_queue<Node, vector<Node>, Node> q;
	int s = 1;
	int count = 0; //假设起点s已经达到过
	int ans = 0;
	//链表前向星加边
	inline void add_edge(int u, int v, int w) {
    
    
		cnt++;
		e[cnt].to = v;
		e[cnt].w = w;
		e[cnt].next = head[u];
		head[u] = cnt;
	}

	void prime() {
    
    
		cin >> n >> m;
		e.resize(2*m + 1);
		head.resize(n + 1, 0);
		dis.resize(n + 1, INF);
		visit.resize(n + 1, false);
		for (int i = 1; i <= m; ++i)
		{
    
    
			int u, v, w;
			cin >> u >> v >> w;
			add_edge(u, v, w);
			add_edge(v, u, w);
		}
		dis[1] = 0;
		q.push(Node(1, 0));
		//下面的过程同迪杰斯特拉算法
		while (!q.empty() && count < n)
		{
    
    
			int u = q.top().pos;
			int d = q.top().w;
			q.pop();
			if (visit[u]) continue;  
			visit[u] = true;
			ans += d;
			++count;
			for (int i = head[u]; i != 0; i = e[i].next)
			{
    
    
				int y = e[i].to;
				if (dis[y] > e[i].w)
				{
    
    
					dis[y] = e[i].w;
					q.push(Node(y, dis[y]));
				}
			}
		}
		if (count == n)
			cout << ans << endl;
		else
			cout << "orz" << endl;
	}
};

int main() {
    
    

	//freopen("in.txt", "r", stdin);
	Solution s;
	s.prime();
	return 0;

}

猜你喜欢

转载自blog.csdn.net/sddxszl/article/details/114055590