ACM第四站————最小生成树(克鲁斯卡尔算法)

Posted Asimple

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM第四站————最小生成树(克鲁斯卡尔算法)相关的知识,希望对你有一定的参考价值。

都是生成最小生成树,库鲁斯卡尔算法与普里姆算法的不同之处在于——库鲁斯卡尔算法的思想是以边为主,找权值最小的边生成最小生成树。

 

同样的题目:最小生成树

题目描述
求一个连通无向图的最小生成树的代价(图边权值为正整数)。
输入
第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算。以下有N个图,第i图的第一行是一个整数M(1<=M& lt;=50),表示图的顶点数,第i图的第2行至1+M行为一个M*M的二维矩阵,其元素ai,j表示图的i顶点和j顶点的连接情况,如果 ai,j=0,表示i顶点和j顶点不相连;如果ai,j>0,表示i顶点和j顶点的连接权值。
输出
每个用例,用一行输出对应图的最小生成树的代价。
样例输入
1
6
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0
样例输出
15

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 22
using namespace std;
int map[MAXN][MAXN], n;
int p[MAXN];
struct Edge {
    int begin, end, weight;
    bool operator < (const Edge& a) const {
        return weight < a.weight;
    }
}edges[MAXN];
int Find(int *p, int f) { while ( p[f] > 0 ) f = p[f];   return f; }
void Dijkstra()
{
    int tim = 0;
    for (int i = 0; i < n; i ++)
        for (int j = i+1; j < n; j ++) {
            if ( map[i][j] ) {
                edges[tim].begin = i;
                edges[tim].end = j;
                edges[tim].weight = map[i][j];
                ++ tim;
            }
        }
    sort(edges, edges+tim);
    memset(p, 0, sizeof(p));
    int sum = 0;
    for (int i = 0; i < tim; i ++) {
        int x = Find(p, edges[i].begin);
        int y = Find(p, edges[i].end);
        if ( x != y ) {
            p[x] = y;
            sum += edges[i].weight;
        }
    }
    printf("%d\n", sum);
}
int main(void)
{
    int T;
    scanf("%d", &T);
    while ( T -- ) {
        scanf("%d", &n);
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++) scanf("%d", &map[i][j]);
        Dijkstra();
    }
    return 0;
}

 

以上是关于ACM第四站————最小生成树(克鲁斯卡尔算法)的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树 普里姆算法和克鲁斯卡尔算法

使用克鲁斯卡尔算法为以下无向图构造出一棵最小生成树,请画出构造的每一步骤

最小生成树--克鲁斯卡尔算法(Kruskal)

6-2 最小生成树(克鲁斯卡尔算法) (10 分)

C语言数据结构 克鲁斯卡尔算法求无向网的最小生成树。

克鲁斯卡尔算法一定要画图吗