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第四站————最小生成树(克鲁斯卡尔算法)的主要内容,如果未能解决你的问题,请参考以下文章