洛谷P3366
prim
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
int main(){
typedef pair<int,int> P;
const int N=5005;
vector<P> edge[N];
int n,m;
scanf("%d%d",&n,&m);
while(m--){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(u==v)continue;
edge[u].push_back(make_pair(v,w));
edge[v].push_back(make_pair(u,w));
}
int dis[N];
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
bool visit[N]={};
//小根堆
priority_queue<P,vector<P>,greater<P> > q;
q.push(make_pair(0,1));
int ans=0;
while(!q.empty()){
P p=q.top();
int u=p.second;
q.pop();
if(visit[u])continue;
ans+=dis[u];
--n;
if(n==0)break;
visit[u]=true;
//遍历边
for(vector<P>::iterator it=edge[u].begin(),end=edge[u].end();it!=end;++it){
int v=it->first;
if(visit[v])continue;
int w=it->second;
if(w<dis[v]){
dis[v]=w;
q.push(make_pair(w,v));
}
}
}
if(n==0)printf("%d\n",ans);
else printf("orz\n");//找不到最小生成树
return 0;
}
kruskal
#include<cstdio>
#include<queue>
using namespace std;
class Edge{
public:
int u,v,w;
void setEdge(){
scanf("%d%d%d",&u,&v,&w);
}
bool operator<(const Edge& other)const{
return w>other.w;
}
};
const int N=5+2e5;
int parent[N];//并查集
Edge edge[N];
int find_parent(int u){
int p=parent[u];
while(parent[p]!=p)p=parent[p];
//路径压缩
while(u!=p){
int t=parent[u];
parent[u]=p;
u=t;
}
return p;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<m;++i){
edge[i].setEdge();
parent[i+1]=i+1;
}
make_heap(edge,edge+m);//小根堆
int ans=0;
--n;
for(int i=0;i<m;++i){
int u=edge[0].u;
int v=edge[0].v;
int w=edge[0].w;
u=find_parent(u);
v=find_parent(v);
if(u!=v){
ans+=w;
--n;
if(n==0)break;
parent[u]=parent[v];
}
pop_heap(edge,edge+(m-i));//调整堆
}
if(n==0)printf("%d\n",ans);
else printf("orz\n");//找不到最小生成树
return 0;
}