Kruskal 代码模板
基本思路:
新手初学,使用优先队列,免去排序;并查集判环,过程中进行了路径压缩,以提高效率; 然后贪心建立最小生成树, min为最小权值;
另外,同为最小生成树的Prime算法和Kruskal算法的适用问题:
因为Prime算法只于顶点有关,所以它更适用于稠密图;
而Kruskal算法依据于边的权值,所以边越少它速度越快,更适合稀疏图。
#include <stdio.h>
#include <queue>
#define N 100
using namespace std;
struct Node{
int start;
int end;
int price;
friend bool operator < (const Node& a, const Node& b){
return a.price > b.price;
}
};
priority_queue<Node>q;
int v, l; // v为顶点数, l为边数
int father[N];
int get_father(int cur)
{
return cur == father[cur] ? cur : father[cur] = get_father(father[cur]); // 路径压缩
}
int join(int start, int end)
{
int root1 = get_father(start);
int root2 = get_father(end);
if(root1 == root2)
return 0;
father[root1] = root2;
return 1;
}
int kruskal()
{
int ans = 0;
Node cur;
while(!q.empty()){ // 此处可记录边数,以优化
cur = q.top();
q.pop();
if(join(cur.start, cur.end)){
printf("%d -> %d\n", cur.start, cur.end); // 输出路径
ans += cur.price;
}
}
return ans;
}
int main()
{
int i;
Node a;
scanf("%d%d", &v, &l);
for(i = 0; i < v; i ++){
father[i] = i;
}
for(i = 0; i < l; i ++){
scanf("%d%d%d", &a.start, &a.end, &a.price);
q.push(a);
}
printf("\nRoad: \n");
int min = kruskal(); // 最小生成树
printf("LowLoad: %d\n", min);
printf("\nFather: \n"); // 输出father数组
for(i = 0; i < v; i ++)
printf("%d ", father[i]);
printf("\n");
return 0;
}