kruskal算法
#include<iostream>
#include<map>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
struct dot{
int x,y,v;
}p[120],a[120];
int f[120],m,n;
bool cmp(dot &a,dot &b){
return a.v<b.v;
}
int find(int k){
if(f[k]!=k)
return f[k]=find(f[k]);
return f[k];
}//并查集
void krus(){
int ans=0;
//遍历每条边
for(int i=1;i<=m;i++){
int r1=find(p[i].x);
int r2=find(p[i].y);
if(r1!=r2){//如果父节点不相同,说明不在一个环中,可以计入
f[r1]=r2;
ans++;
a[ans]=p[i];//将边记录下来
if(ans==n-1)//边数到n-1退出
break;
}
}
if(ans<n-1){
cout<<"-1";
return ;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
f[i]=i;//每个点的父节点
for(int i=1;i<=m;i++){
cin>>p[i].x>>p[i].y>>p[i].v;
}
sort(p+1,p+m+1,cmp);//对各边的权值排序
krus();
for(int i=1;i<n;i++){
cout<<a[i].x<<" "<<a[i].y<<endl;
}
return 0;
}
prim算法
#include<iostream>
#include<map>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int Inf=0x7f;
struct dot{
int x,y,v;
friend bool operator<(const dot &a,const dot &b){
return a.v>b.v;
}//重载运算符,升序排列
}now,a[120];
int p[120][120];//存图
int vis[120];//标记
int n,m;
priority_queue<dot>q;//使用优先队列优化
void prim(int key){
vis[key]=1;
for(int i=1;i<n;i++){
for(int j=1;j<=n;j++){
if(!vis[j]){
now.x=key;//from
now.y=j;//to
now.v=p[key][j];
q.push(now);
}
}
//因为是每次有新的标记点,就会push进去此点连接的其他点信息
//而其他点可能在之前就已经标记过,所以需要弹出
while(!q.empty()&&vis[q.top().y]) q.pop();
if(q.empty()) break;
now=q.top();
q.pop();
key=now.y;//key值记得更新
vis[key]=1; //将此点标记
a[i]=now; //记录边
}
}
int main(){
cin>>n>>m;
fill(p[0],p[0]+120*120,Inf);//千万记得初始化为Inf
for(int i=1;i<=m;i++){
int x,y,v;
cin>>x>>y>>v;
p[x][y]=p[y][x]=v;
}
prim(1);
for(int i=1;i<n;i++)
cout<<a[i].x<<" "<<a[i].y<<endl;
return 0;
}