#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 10000
#define MAXM 1000
#define INF 0X7FFFFFFF
struct node{//1 原图 2 生成树 生成树要存起来
int to;
int weight;
int next;
}edge1[MAXM],edge2[MAXM];
int head1[MAXN],head2[MAXN];
int cnt1,cnt2;
int n,m;
void Init(){
cnt1=0;
cnt2=0;
memset(edge1,0,sizeof(edge1));
memset(head1,0,sizeof(head1));
memset(edge2,0,sizeof(edge2));
memset(head2,0,sizeof(head2));
}
void Add(int x,int y,int z,int num){
if(num==1){
cnt1++;
edge1[cnt1].to=y;
edge1[cnt1].weight=z;
edge1[cnt1].next=head1[x];
head1[x]=cnt1;
}
else{
cnt2++;
edge2[cnt2].to=y;
edge2[cnt2].weight=z;
edge2[cnt2].next=head2[x];
head2[x]=cnt2;
}
}
void Prim(){
int i,j,t;
int Min,minIndex,sum=0;
int *dis=new int[n];//当前生成树内的点 到树外其他点的最短距离
int *parent=new int[n];//生成树中每个节点的父节点
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dis[1]=0;//把1节点加入树中 加入树中的,dis均为0
parent[1]=0;
for(i=1;i<=n;i++){
Min=INF;
for(j=1;j<=n;j++){
if(dis[j]!=-1&&dis[j]<Min){
Min=dis[j];
minIndex=j;
}
}
if(Min==INF){//没有最小生成树
cout<<"ERROR"<<endl;
return;
}
sum+=dis[minIndex];
Add(parent[minIndex],minIndex,dis[minIndex],2);
dis[minIndex]=-1;
for(t=head1[minIndex];t;t=edge1[t].next){
if(dis[edge1[t].to]>edge1[t].weight){
dis[edge1[t].to]=edge1[t].weight;
parent[edge1[t].to]=minIndex;
}
}
}
cout<<sum<<endl;
delete dis;
}
int main(){
int x,y,z;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
Add(x,y,z,1);
Add(y,x,z,1);
}
Prim();
return 0;
}
可以看出,此算法与单源最短路Dijkstra算法很像,此代码也可以进行堆优化:
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
#define INF 0X7FFFFFFF
int n,m,cnt,head[1005];
struct node{
int to;
int weight;
int next;
}edge[10000];
struct node1{
int to,cost;
node1(int x,int y):to(x),cost(y){}
bool operator<(node1 a)const{
return this->cost>a.cost;
}
};
void Add(int x,int y,int w){
cnt++;
edge[cnt].to=y;
edge[cnt].weight=w;
edge[cnt].next=head[x];
head[x]=cnt;
}
void Prim(){//设点从1到N
int sum=0,dis[n+1],book[n+1];
priority_queue<node1> q;
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dis[1]=0;
memset(book,0,sizeof(book));
q.push(node1(1,0));
while(!q.empty()){
node1 t=q.top();
q.pop();
if(book[t.to]){
continue;
}
sum+=t.cost;//由此可以看出,不加book标记不可以
book[t.to]=1;
for(int i=head[t.to];i;i=edge[i].next){
if(edge[i].weight<dis[edge[i].to]){
dis[edge[i].to]=edge[i].weight;
q.push(node1(edge[i].to,edge[i].weight));
}
}
}
cout<<sum<<endl;
}
int main(){
int x,y,w;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>w;
Add(x,y,w);
Add(y,x,w);
}
Prim();
return 0;
}