注意:
1、并查集的巧妙应用。
一、大致框架
1、边的数据结构定义
struct edge
{
int u; //u、v: 边的两个端点
int v;
int cost;
}E[maxe];
2、比较函数
bool cmp(edge a,edge b)
{
return a.cost<b.cost;
}
3、kruskal函数
int father[n];
int findFather(int x);
{
}
int kruskal(int n,int m)
{
int ans=0;
int num_edge=0;
for(int i=1;i<=n;i++)
{
father[i]=i;
}
sort(E,E+m,cmp);
for(int i=0;i<m;i++)
{
int faU=findFather(E[i].u);
int faV=findFather(E[i].v);
if(faU!=faV)
{
father[faU]=faV;
ans+=E[i].cost;
NumEdge++;
if(Num_Edge==n-1) break;
}
}
if(Num_Edge!=n-1) return -1;
else return ans;
}
二、kruskal测试代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxv=110;
const int maxe=10010;
struct edge
{
int u;
int v;
int cost;
}E[maxv];
bool cmp(edge a,edge b)
{
return a.cost<b.cost;
}
//1、并查集部分
int father[maxv];
int findFather(int x)
{
int a=x;
while(x!=father[x])
{
x=father[x];
}
//路径压缩
while(a!=father[a])
{
int z=a;
a=father[a];
father[z]=x;
}
return x;
}
//2、kruskal部分
int kruskal(int n,int m)
{
int ans=0;
int Num_Edge=0;
for(int i=0;i<n;i++) //并查集初始化
{
father[i]=i;
}
sort(E,E+m,cmp);
for(int i=0;i<m;i++)
{
int faU=findFather(E[i].u);
int faV=findFather(E[i].v);
if(faU!=faV)
{
father[faU]=faV;
ans+=E[i].cost; //加上这条边的权重
Num_Edge++;
if(Num_Edge==n-1) break;
}
}
if(Num_Edge!=n-1) return -1;
else return ans;
}
int main()
{
int n;
int m;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&E[i].u,E[i].v,E[i].cost);
}
int ans=kruskal(n,m);
printf("%d\n",ans);
return 0;
}