终于学到图论啦!!今天练习的是prim算法,用于计算最小生成树的。(我觉得图论的数据结构真的很难!!!
2025.3.14 8:32二编,附代码~
#include<bits/stdc++.h>
using namespace std;
//本题目标是n个城市相连的最小生成树
int n;
const int N=6000;
double x[N],y[N];
int vis[N];
double ans=0.0;
vector<int>e[N];//记录邻居点
double distance(int i,int j)
{
return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
typedef pair<double,int>pp;
void prim(){
priority_queue<pair<double,int>,vector<pp>,greater<pp>>q;
//<距离,邻居点>
q.push(make_pair(0,1));
int cnt=0;
while(!q.empty()&&cnt!=n)
{
int u=q.top().second;//最近的邻居点
if(vis[u])
{
q.pop();
continue;
}
cnt++;
vis[u]=1;
ans+=q.top().first;
q.pop();
for(auto v:e[u])
{
if(!vis[v])
q.push(make_pair(distance(u,v),v));
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)continue;
e[i].push_back(j);
}
}
prim();
cout<<ans;
return 0;
}
代码中有几行没看懂,之前也没见过,是priority_queue的定义和pair等问题,查找了资料,现在记录一下~
typedef pair<double,int>pp;
void prim(){
priority_queue<pair<double,int>,vector<pp>,greater<pp>>q;
}
-
priority_queue优先队列
该题定义了这样一个priority_queue,我一开始没看懂里面的三个变量是什么意思。
首先,优先队列是一种特殊的队列,队头始终是所有元素的最值。例如,最大优先队列,弹出的顺利是从大到小,队头永远是最大的。
在C++中,priority_queue
的声明涉及三个模板参数:元素类型、底层容器类型和比较函数对象类型。
第一个参数 pair<double, int>
:
第二个参数 vector<pp>
: 指定优先队列的底层容器为 vector<pp>
(即 vector<pair<double, int>>,所以前面定义pp应该是为了简化一些代码哈
)。
第三个参数 greater<pp>
: 定义元素的比较规则为最小堆(从小到大排序)。
注意:在c++中,priority_queue默认最大堆,从大到小排序(这里也跟我想的不一样欸?我记得其他的排序都是默认从小到大的欸)
在本题在prim算法中,最小堆弹出的顺序是从小到大~因此保证是“路径最短的生成树!”
-
greater<pp>
的原理:
它会调用pair<double, int>
的operator>
来比较元素。对于两个pair
对象a
和b
:- 先比较
a.first
和b.first
(double
部分),first
值较小的pair
优先级更高。 - 如果
a.first == b.first
,则比较a.second
和b.second
(int
部分),second
较小的优先级更高。
- 先比较
q.push(make_pair(0,1));
2.make_pair用法
std::pair主要的作用是将两个数据组合成一个数据,相当于组成一个结构体struct,也是pair。
pair主要的两个成员变量是first和second,这两个变量可以直接使用。
初始化一个pair可以使用构造函数,也可以使用std::make_pair函数,即在需要pair做参数的位置,(比如插入map中的元素)可以直接调用make_pair生成pair对象。
ps:突然想起来之前写题的时候看到过bool const operator什么的比较函数,当时不太会写,有空补上这方面的资料。
参考了以下文章,感谢~
C++基础——C++ make_pair用法_make pair-优快云博客
【用法学习】C++ pair用法及使用sort函数对pair数据进行排序_c++ pair排序-优快云博客