给定一个无向图,如果他的某个子图中的任意两个顶点都是连同的并且是一棵树,那么这棵树就叫生成树(Spanning Tree),如果边上有权值,那么使得边权和最小的生成树叫做最小生成树.
首先我们假设有一棵树只包含一个顶点v的树T.然后贪心的取T和其他定点之间连接的最小权值的边,并把它加入到T中.不断进行这个操作,既可以得到一颗生成树了
#include<iostream>
#include<algorithm>
using namespace std;
int par[100];
int rank[100];
void inint(int n)
{
for(int i=0;i<n;i++)
{
par[i]=i;
rank[i]=0;
}
}
//查询树的跟
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);
}
//合并x,y所属的集合
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)return;
if(rank[x]<rank[y])
par[x]=y;
else
{
par[y]=x;
if(rank[x]==rank[y])rank[x]++;
}
}
//判断x,y是否属于同一个集合
bool same(int x,int y)
{
return find(x)==find(y);
}
struct edge{int u,v,cost;};
bool comp(edge e1,edge e2)
{
return e1.cost<e2.cost;
}
edge es[100];
int main()
{
int V,E;
cout<<"请输入顶点数和边数: "<<endl;
cin>>V>>E;
cout<<"请输入连接点和边长: "<<endl;
for(int i=0;i<E;i++)
cin>>es[i].u>>es[i].v>>es[i].cost;
sort(es,es+E,comp);//把权值从小到大排序
inint(V);
int res=0;
for(int i=0;i<E;i++)
{
edge e=es[i];
if(!same(e.u,e.v))//如果要选取的这个顶点未与T区域连接
{
unite(e.u,e.v);//把这个顶点与区域T中的顶底连接
res+=e.cost;
}
}
cout<<res<<endl;
}