克鲁斯卡尔算法的基本思想:
考虑问题的出发点: 为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能地小。
具体做法: 先构造一个只含 n 个顶点的子图 SG,然后从权值最小的边开始,若它的添加不使SG 中产生回路,则在 SG 上加上这条边,如此重复,直至加上 n-1 条边为止。
判断是否产生回路可以用并查集
每次用选择权边最小的边可以用优先队列
#include < iostream >
#include < queue >
using namespace std;
const long Max = 101 ;
struct node
{
long from;
long to;
long cost;
} ;
int set [Max];
priority_queue < node > q;
bool operator < ( const node & a, const node & b)
{
return a.cost > b.cost;
}
long find( long x)
{
long i = x,r = x,j;
while ( set [r] != r)
r = set [r];
while (i != r)
{
j = set [i];
set [i] = r;
i = j;
}
return r;
}
void merge( long a, long b)
{
long x,y;
x = find(a);
y = find(b);
if (x != y)
set [x] = y;
}
long Kruskal()
{
long rs = 0 ,i;
node e;
for (i = 0 ;i < Max;i ++ )
set [i] = i;
while ( ! q.empty())
{
e = q.top();
q.pop();
if (find(e.from) != find(e.to))
{
merge(e.from,e.to);
rs += e.cost;
}
}
return rs;
}
int main()
{
/*
while(!q.empty()) //清空
{
q.pop();
}
while(m--) //边数
{
scanf("%ld%ld%ld",&e.from,&e.to,&e.cost);
q.push(e);
swap(e.from,e.to);//无向图
q.push(e);
}
rs=Kruskal();
printf("%ld/n",rs);
}
return 0; */
}