(一) Kruskal算法(优先队列实现)
由上一篇知道,Kruskal算法是对边的权值进行从小到大的排序,然后运用“加边法”实现;上一篇对边的权值进行排序的时候是用结构体自定义排序实现,当然,我们也可以用优先队列实现;
【算法概述】:存图时依然用结构体,和上一篇基本差不多,只是在对边的权值排序的时候用到了优先队列(优先队列)的自定义排序。
注:这里,优先队列的数据类型是结构体,往优先队列里压元素时需要注意一下:
node k;
for (i = 0; i < m; i++)
{
cin >> k.from >> k.to >> k.p;
pq.push(k);
}
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define N 1000
int par[N];
int rank1[N];
int sum;
struct node
{
int from;
int to;
int p;
}f1,f2;
struct cmp
{
bool operator()(node f1, node f2)
{
return f1.p > f2.p;
}
};
priority_queue<node,vector<node>,cmp> pq;
void inin(int n)
{
int i;
for (i = 0; i < n; i++)
{
par[i] = i;
rank1[i] = 1;
}
}
int find(int x)
{
if (x == par[x])
return x;
else
return par[x] = find(par[x]);
}
bool join(int a, int b)
{
int fa;
int fb;
fa = find(a);
fb = find(b);
if (fa == fb)
{
return false;
}
else if (rank1[fa] > rank1[fb])
{
par[fb] = fa;
}
else {
if (rank1[fa] == rank1[fb])
{
rank1[fb]++;
}
par[fa] = fb;
}
return true;
}
void krustal(int n)
{
int i;
while (pq.empty() != 1)
{
int x = pq.top().from;
int y = pq.top().to;
int s = pq.top().p;
pq.pop();
if (join(x, y))
sum += s;
}
cout << sum << endl;
}
int main()
{
int n, m;
cin >> n >> m;
inin(n);
int i;
sum = 0;
int a, b, c;
node k;
for (i = 0; i < m; i++)
{
cin >> k.from >> k.to >> k.p;
pq.push(k);
}
krustal(m);
return 0;
}