int par[MAX_N];
void init(int n)//初始化
{
for(int i=1;i<=n;i++)
par[i]=i;
}
int Find(int x)//寻找根节点
{
if(x==par[x])
return x;
return par[x]=Find(par[x]);//路径压缩
}
void unite(int x,int y)//连接两个不同集合
{
x=Find(x);
y=Find(y);
if(x==y)
return ;
par[x]=y;
}
bool same(int x,int y)//判断是否在同一集合
{
return Find(x)==Find(y);
}
struct edge
{
int u,v,cost;
}E[MAX_N];
bool cmp(edge a,edge b)
{
return a.cost<b.cost;
}
int cruskal(int n,int m)//n个点,m条边
{
int cost_sum=0,edge_num=0;
init(n);
sort(E,E+m,cmp);
for(int i=0;i<m;i++)
{
int u=E[i].u;
int v=E[i].v;
if(!same(u,v))//如果不在同一集合,更新数据
{
unite(u,v);
cost_sum+=E[i].cost;
edge_num++;
if(edge_num==n-1)//连接n个点最少需要n-1条边
break;
}
}
if(edge_num==n-1)
return cost_sum;
return -1;
}