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 <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>

using namespace std;
#define INF 0xffffff
const int maxn = 25 ;
int n, num;
int G[maxn][maxn];
int a[maxn];
struct Edges//边集数组
{
    int Start ;
    int End;
    int weight;
    bool operator < (const Edges& a) const
    {
        return weight < a.weight ;
    }
}edges[maxn];

int get_Edges()//构建边集数组
{
    int len = 0 ;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if( G[i][j] )
            {
                edges[len].Start = i ;
                edges[len].End = j ;
                edges[len].weight = G[i][j] ;
                ++ len ;
            }
        }
    }
    sort(edges,edges+len);
    return len ;
}

int Find(int *p, int num)
{
    while( p[num] > 0 )
        num = p[num] ;
    return num ;
}

void kruskal()
{
    int cnt = get_Edges();
    memset(a,0,sizeof(a));
    int sum = 0 ;
    for(int i=0; i<cnt; i++)
    {
        int x = Find(a, edges[i].Start);
        int y = Find(a,edges[i].End);
        if( x != y )
        {
            a[x] = y ;
            sum += edges[i].weight;
            //打印顶点以及对应权值
            //printf("%d %d == %d", edges[i].Start, edges[i].End, edges[i].weight);
        }
    }
    cout << sum << endl ;
}

int main()
{
    int T ;
    cin >> T ;
    while( T -- )
    {
        cin >> n ;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                cin >> G[i][j] ;
        kruskal();
    }

    return 0;
}

 

转载于:https://www.cnblogs.com/Asimple/p/5551307.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值