博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hihocoder(1098) 最小生成树Kruskal
阅读量:6992 次
发布时间:2019-06-27

本文共 1498 字,大约阅读时间需要 4 分钟。

Kruskal比Prim简单的多,对已知边排序,然后从排序的边中跳出N-1条最短的来就可以了,当然,如果在挑的过程中出现环,就丢掉继续找,就只这么直接。

如何判定有没有环?很简单,用并查集就可以。

比如a-b,b-c,c-a构成了环,那么a-b合并,b-c合并后,如果紧接着最小边是c-a,那么并查集的find(c,a)操作就会告诉你,c,a是同一个环内,跳过,继续。

总结一下:

(1)对已知边排序(如果用数组存顶点,那么直接用qsort()就行了,如果用vector,那么sort()就行了)

(2)从已排序的边中找出一条最小边,如果该边与当前最小生成树形成环,跳过,否则合并端点e.a,e.b,将当前边加入最小生成树内。

(3)循环。

由于挑选的过程是一个O(e)的过程,那么其实Kurskal的时间复杂度主要由其排序时间决定,O(eloge)。这也是Kruskal非常适合稀疏图的原因。

1 struct Edge 2 { 3     int a; 4     int b; 5     int weight; 6 }; 7  8 int edgeCmp(const void* ea, const void* eb) 9 {10     return reinterpret_cast
(ea)->weight - reinterpret_cast
(eb)->weight;11 }12 13 int N, M;14 int p[100010];15 Edge e[1000010];16 17 int find(int i) 18 {19 if (p[i] == i)20 return i;21 return p[i] = find(p[i]);22 }23 24 void merge(int i, int j)25 {26 if (find(i) != find(j))27 p[find(i)] = find(j);28 }29 30 int kruskal() 31 {32 int res=0;33 qsort(e, M, sizeof(Edge), edgeCmp);34 for (int i = 0; i < M; ++i) 35 {36 if (find(e[i].a) == find(e[i].b))37 continue;38 res += e[i].weight;39 merge(e[i].a, e[i].b);40 }41 42 return res;43 }44 45 int main()46 {47 scanf("%d%d", &N, &M);48 for (int i = 1; i <= N; ++i) p[i] = i;49 for (int i = 0; i < M; ++i)50 scanf("%d%d%d", &(e[i].a), &(e[i].b), &(e[i].weight));51 52 printf("%d\n", kruskal());53 54 return 0;55 }
View Code

 

转载于:https://www.cnblogs.com/sheepsheep/p/4419118.html

你可能感兴趣的文章
Visual Studio 2008常见问题
查看>>
【洛谷 P4254】 [JSOI2008]Blue Mary开公司(李超线段树)
查看>>
scrapy初体验 - 安装遇到的坑及第一个范例
查看>>
OC内存管理
查看>>
C#中Split用法
查看>>
3月6日 c#语言
查看>>
[LeetCode] Surrounded Regions, Solution
查看>>
MySQL系列:数据库基本操作(1)
查看>>
cpu真实核数
查看>>
hdu1058(dp)
查看>>
android EditText与TextView几个常用的属性
查看>>
SDN第五次上机作业
查看>>
redis 重要的配置参数
查看>>
Oracle 高级编程 01 ~
查看>>
JS重点整理之JS原型链彻底搞清楚
查看>>
springboot 配置文件
查看>>
浏览器插件 - Chrome 对 UserScript 的声明头(metadata)兼容性一览
查看>>
两个list<object> 比较 得到相同数据 差异数据
查看>>
The road to learning English-Writing
查看>>
Codeforces 990B :Micro-World
查看>>