feat: 添加P1967.cpp实现最小生成树算法

实现基于优先队列和并查集的最小生成树算法,用于解决图论中的连通问题。包含边的结构定义、合并操作和结果输出功能。
This commit is contained in:
Zengtudor 2025-09-02 11:04:17 +08:00
parent e018452176
commit 727facbee0
2 changed files with 78 additions and 0 deletions

0
EOF
View File

78
src/9/2/P1967.cpp Normal file
View File

@ -0,0 +1,78 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <ios>
#include <iostream>
#include <queue>
#include <vector>
using ll = int64_t;
struct Edge{
ll to{};
ll w{};
inline bool operator<(const Edge&r){
return w<r.w;
}
};
struct XYZ{
ll x{},y{},z{};
inline bool operator<(const XYZ&r)const{
return z<r.z;
}
};
ll n,m;
std::vector<std::vector<Edge>> edg;
std::vector<ll> unf;
std::priority_queue<XYZ> pq;
ll mergednum = 0;
static inline ll find(ll idx){
if(idx==unf[idx])return idx;
return unf[idx]=find(unf[idx]);
}
static inline void merge(ll a,ll b){
unf[find(a)]=find(b);
}
static inline bool ismerged(ll a,ll b){
return find(a)==find(b);
}
int main(){
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n>>m;
edg.resize(n+1);
unf.resize(n+1);
for(ll i=1;i<=n;i++){
ll x,y,z;
std::cin>>x>>y>>z;
pq.emplace(x,y,z);
}
while(pq.size() && mergednum < n-1){
auto[x,y,z] = pq.top();
pq.pop();
if(ismerged(x, y))continue;
edg[x].emplace_back(y,z);
edg[y].emplace_back(x,z);
merge(x, y);
mergednum++;
}
for(ll u=1;u<=n;u++){
for(auto [v,w]:edg[u]){
char buff[128];
memset(buff, 0, sizeof(buff));
sprintf(buff,"point %lld to %lld weight %lld\n",u,v,w);
std::cout<<buff;
}
}
}