您的位置:首页 > 其它

最小生成树---Kruskal---模板

2018-01-30 14:22 375 查看
#include<cstdio>
#include<cstring>
#include<string>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#define ll long long
using namespace std;
struct edge{
int u;
int v;
int w;
};
struct edge e[10];
bool cmp(edge a,edge b){
if(a.w<b.w){
return 1;
}
else
return 0;
}
int n,m;
int f[51]={0},sum=0;

int getf(int v)//找祖先233
{
if(f[v]==v)
return v;
else {
//路径压缩???
f[v]=getf(f[v]);
return f[v];
}
}
//并查集合并两子集的函数;
int merge(int v,int u){
int t1,t2;
t1=getf(v);
t2=getf(u);

if(t1!=t2)//判断两点是否在同一集合内;
{
f[t2]=t1;
return 1;
}
return 0;
}
int main(){
int count=0;
while(~scanf("%d %d",&n,&m)){
//读入n和m,n表示顶点个数,m表示边的个条数;
for(int i=1;i<=m;i++){
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
}
sort(e+1,e+1+m,cmp);//按照权值从小到大进行快速排序;

for(int i=1;i<=n;i++){
f[i]=i; //并查集初始化
}
//Kruskal算法核心部分;
for(int i=1;i<=m;i++){ //开始从小到大枚举每一条边;

if(merge(e[i].u,e[i].v)){ //如果目前尚未不连通,则选用这条边;
count++;
sum+=e[i].w;
}
if(count==n-1){ //直到选用了n-1条边之后退出循环;
break;
}

}
printf("%d\n",sum);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: