P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
普通版
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NOTLE ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl '\n'
#define T int TT;cin >> TT;while (TT--)
#define lint long long
#define pb push_back
#define eb emplace_back
int last[400010],ne[400010],to[400010],w[400010],cnt=0;
int d[5010],n,m,ans;
int vis[5010];
void add(int x,int y,int z){//链式前向星存边
to[++cnt]=y;
ne[cnt]=last[x];
last[x]=cnt;
w[cnt]=z;
}
int prim(){
memset(d,INF,sizeof(d));//没有搜索到的点设置为最大值
for(int i=last[1];i;i=ne[i]){
d[to[i]]=min(d[to[i]],w[i]);
}
int now=1,tot=0;
while(++tot<n){//最小生成树边数等于点数n-1
int minn=INF;
vis[now]=1;//标记走过的点
for(int i=1;i<=n;++i) //找最短边连的点
if(!vis[i] && minn>d[i]){
minn=d[i];
now=i;
}
if(minn==INF) return -1; //如果没找到,说明最小生成树不存在
ans+=minn;
for(int i=last[now];i;i=ne[i]) //枚举now的所有连边,更新d数组
if(d[to[i]]>w[i] && !vis[to[i]]){
d[to[i]]=w[i];
}
}
return ans;
}
int main(){
cin >> n >> m;
for(int i=1;i<=m;++i){
int x,y,z;
cin >> x >> y >> z;
add(x,y,z),add(y,x,z);
}
int pr=prim();
if(pr!=-1) cout << pr;
else cout << "orz";
return 0;
}
堆优化版
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NOTLE ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl '\n'
#define T int TT;cin >> TT;while (TT--)
#define lint long long
#define pb push_back
#define eb emplace_back
int last[400010],ne[400010],to[400010],w[400010],cnt=0,tot=0;
int d[5010],n,m,ans;
int vis[5010];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> p; //小根堆
void add(int x,int y,int z){
to[++cnt]=y;
ne[cnt]=last[x];
last[x]=cnt;
w[cnt]=z;
}
int prim(){
memset(d,INF,sizeof(d));//没有搜索到的点设置为最大值
p.push(make_pair(0,1));
while(!p.empty()){
int now=p.top().second,nowa=p.top().first;
p.pop();
if(vis[now]) continue;
vis[now]=1;
ans+=nowa;
for(int i=last[now];i;i=ne[i])
if(d[to[i]]>w[i] && !vis[to[i]]){
d[to[i]]=w[i];
p.push(make_pair(d[to[i]],to[i]));
}
tot++;
}
return ans;
}
int main(){
cin >> n >> m;
for(int i=1;i<=m;++i){
int x,y,z;
cin >> x >> y >> z;
add(x,y,z),add(y,x,z);
}
int pr=prim();
if(tot==n) cout << pr;
else cout << "orz";
return 0;
}