码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-06-01 23:04:46      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

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

 

同样的题目:最小生成树

题目描述
求一个连通无向图的最小生成树的代价(图边权值为正整数)。
输入
第 一行是一个整数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第四站————最小生成树(克鲁斯卡尔算法)

标签:

原文地址:http://www.cnblogs.com/Asimple/p/5551307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!