首页 > 其他分享 >H-prim 最小生成树

H-prim 最小生成树

时间:2023-07-29 15:23:23浏览次数:34  
标签:forup prim min int tree 最小 生成 include

知道了prim最小生成树算法,我们发现每次找距离最小的点的操作和dijkstra算法中的操作很像,所以我们考虑是否可以将迪杰的优化套到prim上,也即用优先队列

时间复杂度大概是O(mlogm)

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

#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<queue>
#pragma GCC target("avx") 
#pragma GCC optimize (2)
#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];
priority_queue<pair<int, int>> q;//min_dis from the tree and corresponding node 
int min_d[N];//min_dis of node i from the tree
bool vis[N];//if in the tree
int n, m;
int sum;

bool prim(int s)//堆优化的适合稀疏图,复杂度O(mlogm),不优化是O(n^2)
{
	forup(i, 1, n) min_d[i] = INF;//INF == (1 << 31) - 1
	q.push({0, s});
	min_d[s] = 0;
	int cnt = 0;
	
	while(!q.empty())
	{
		int u = q.top().second; q.pop();
		
		if(vis[u]) continue;
		else vis[u] = true;
		
		sum += min_d[u];
		
		if(min_d[u] != INF) cnt++;//如果不连通,不更新,不计数 
		
		for(auto x: e[u])
		{
			int v = x.first, w = x.second;
			if(min_d[v] > w)
			{
				min_d[v] = w;
				q.push({-w, v});
			}
		}
		
		if(cnt == n) return 1;
	}
	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;
}

标签:forup,prim,min,int,tree,最小,生成,include
From: https://www.cnblogs.com/V-sama/p/17589870.html

相关文章

  • 语音合成技术汇总1:Glow-TTS:通过单调对齐实现文本到语音的生成流
    今天开始开一期语音合成经典论文的翻译Glow-TTS:通过单调对齐实现文本到语音的生成流摘要:最近,文本到语音(Text-to-Speech,TTS)模型,如FastSpeech和ParaNet,被提出以并行方式从文本生成mel频谱图(mel-spectrograms)。尽管并行TTS模型具有优势,但它们不能在没有自回归TTS模型作为外部对齐......
  • 利用 timeb 生成毫秒级别随机数
    众所周知,重复打开相同的可执行文件,想要输出的数不同,往往需要以时间作为随机种子。如:#include<bits/stdc++.h>intmain(){srand(time(0));inta=rand();printf("%d\n",a);}但是,以这种方式,在每1秒内重复运行这个程序,输出的随机数都是相同的。那么,想要......
  • 生成函数
    生成函数生成函数是一种将一个序列映射成一个多项式的方式,具体而言,对于无限/有限序列\(a_1,a_2,\dots,a_n,\dots\),记\(g(x)=a_1+a_2x+a_3x^2+\dots+a_nx^n+\dots\),则\(g(x)\)为原序列的生成函数。生成函数可以用于解决一些计数问题,它可以利用乘法原理。例如有\(1g,2g,4g\)......
  • C++ Primer Plus学习笔记
    仅限main函数,如果没有返回语句,编译器会加隐含的返回语句:return0;WIN1064位系统中,sizeof(int)==sizeof(long)==4.C++17之后,新增byte数据类型,在标头<cstddef>中定义,取值范围[0-255],初始化:std::byteb{42};char取值范围[-128,127]原始字符串R"(string)"R"+*(......
  • 【模板】数论基础:exGCD,exCRT,inverse,Lucas,BSGS,primitive root
    7.29数论WIP\(a\equivb\pmodp\Rightarrow\frac{a}{d}\equiv\frac{b}{d}\pmod{\frac{p}{d}},d=\gcd(a,b,p)\)。exGCD若\((a,b)=1\),则\(0\leqx<b\),\(ax\bmodb\)互不相同,有一个是\(1\)。证明:\(ax_1\equivax_2\pmodb\)则\((x_1-x_2)a|b\),因为......
  • Qt 生成应用程序(二)软件多图标与文件操作
    目录关联某种文件的默认打开方式assocftype解决方案设置文件默认图标应用软件添加多个图标综合方法嘿,各位Qt桌面应用开发的同学们(应该Qt大部分应用场景就是这个吧......
  • 词向量与Emoji表情生成器
    1词向量因为我们的输入是一些文本,所以我们需要将这些文本转化为词向量。如何加载训练好了的词向量这里我们使用50维的向量来表示单词:defread_glove_vecs(glove_file):withopen(glove_file,'r',encoding='utf8')asf:words=set()word_to_vec_......
  • G3、CGAN|生成手势图像
    ......
  • 生成器/range/yield/模块
    生成器对象(自定义迭代器) 本质其实还是迭代器只不过是我们自己通过写代码产生 也是有__iter__和__next__方法 defindex():print('你还记得我吗?')yield123'''生成器对象也是节省存储空间的特性与迭代器对象一致'''"""当函数体代码中含有yield关键字......
  • 代码随想录算法训练营第二天| LeetCode 977.有序数组的平方 ,209.长度最小的子数组 ,59.
    977.有序数组的平方     题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/    文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html    视频讲解: https://www.bili......