zoukankan      html  css  js  c++  java
  • 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;
    }
    
    低调做人,高调做事。
  • 相关阅读:
    登录的验证码
    分页效果
    弹出新窗口
    添加软键盘
    左侧菜单
    制作导航
    DEV第三方控件的GalleryControl控件
    div悬浮在屏幕的中间及点击按钮关闭弹出框
    鼠标经过图片时向前突出并放大图片
    UIImageView实现加载网络gif图片
  • 原文地址:https://www.cnblogs.com/Asimple/p/5551307.html
Copyright © 2011-2022 走看看