prim 最小生成树

发布时间 2023-07-29 15:16:00作者: eternal_visionary

最小生成树,也就是对一个无向图,找到其中边权和最小的树

prim算法的思路就是每次找离当前生成树距离最小的点,逐渐扩大生成树的规模

时间复杂度差不多是O(n^2)

例题:洛谷 P3366 【模板】最小生成树

#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#define INF 0x7fffffff
#define forup(i, l, r) for(int i = l; i <= r; i++)
using namespace std;
const int N = 5005;
vector<pair<int, int>> e[N];
int min_d[N];//当前生成树到i点的最短距离 
bool vis[N];//是否在最小生成树内 
int n, m;
int sum;

bool prim(int s)
{
	memset(min_d, 127, sizeof min_d);
	min_d[s] = 0;
	int cnt = 0;
	forup(i, 1, n)//加入n个点,循环n次 
	{
		int u = 0;
		forup(j, 1, n)//找最短距离的点 
		{
			if(!vis[j] && min_d[j] < min_d[u]) u = j;
		}
		vis[u] = true;
		sum += min_d[u];
		
		if(u != 0) cnt++;//如果不连通,不更新,不计数 
		
		for(auto x: e[u])
		{
			int v = x.first, w = x.second;
			min_d[v] = min(min_d[v], w);
		}
	}
	return cnt == n;
} 
int main()
{
	cin>>n>>m;
	forup(i, 1, m)
	{
		int u, v, w;
		cin>>u>>v>>w;
		e[u].push_back({v, w});
		e[v].push_back({u, w});
	}
	if(prim(1))
	{
		cout<<sum;
	}
	else cout<<"orz";
	return 0;
}