Prim算法求最小生成树
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N=4e5+10;
vector<pii> e[N];
int d[N],vis[N];
int n,m;
int ans=0, cnt=0;
priority_queue<pii> q;
bool prim(){ //堆优化版prim
for(int i=0;i<=n;i++) d[i]=0x3f3f3f3f;
d[1]=0; q.push({0,1});
while(q.size()){
int u=q.top().second; q.pop();
if(vis[u]) continue;
vis[u]=1;
ans+=d[u]; cnt++;
for(auto ele: e[u]){
int v=ele.first, w=ele.second;
if(d[v]>w){
d[v]=w;
q.push({-d[v], v});//小根堆找离集合最近的点v;
}
}
}
return cnt==n;
}
int main(){
cin>>n>>m;
for(int i=0; i<m; i++){
int a,b,c; cin>>a>>b>>c;
e[a].push_back({b,c});
e[b].push_back({a,c});
}
if(prim()) cout<<ans;
else cout<<"impossible";
}
//O(logn*n)朴素做法
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N=4e5+10;
vector<pii> e[N];
int d[N],vis[N];
int n,m;
int ans=0, cnt=0;
bool prim(){
for(int i=0; i<=n; i++) d[i]=0x3f3f3f3f;
d[1]=0;
for(int i=1; i<=n; i++){
int u=0;
for(int j=1;j<n;j++)
if(!vis[j]&&d[j]<d[u])
u=j;//遍历找到并标记u出圈
vis[u]=1;
ans+=d[u];
if(d[u]!=0x3f3f3f3f) cnt++;
for(auto ele: e[u]){
int v=ele.first, w=ele.second;
if(d[v]>w) d[v]=w;
}
}
return cnt==n;
}
int main(){
cin>>n>>m;
for(int i=0; i<m; i++){
int a,b,c; cin>>a,b,c;
e[a].push_back({b,c});
e[b].push_back({a,c});
}
if(prim()) cout<<ans;
}