kruskal 最小生成树算法
Posted lqsukida
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kruskal 最小生成树算法相关的知识,希望对你有一定的参考价值。
今天在vjudge上做了这题,非常水的一道板子题,一眼就能看出来是个最小生成树
然后就用prim随便做了下
结果就超时了TT
但是我不会kruskal啊,没办法,就随便看了下这个算法的思想,发现还挺好理解的?就是个贪心+并查集
于是又一次自信满满地码完之后一交
又双叒超时了TT
最后错了两三次之后不得已跑到csdn上看了下这个模板……发现自己还是认识得浅薄了点儿,所以不够快TT
下面直接放代码,然后理解的话先标下方等以后有时间了做成注释
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int N = 105, M = 10050; 7 int par[N], ans, n, m, t; 8 struct edge { int u, v, w;} e[M]; 9 bool cmp(edge a, edge b){ return a.w < b.w;} 10 11 long long read() 12 { 13 char ch=getchar(); 14 long long x=0; 15 while(ch>‘9‘ || ch<‘0‘)ch=getchar(); 16 while(ch>=‘0‘ && ch<=‘9‘)x=(x<<1)+(x<<3)+(ch^‘0‘),ch=getchar(); 17 return x; 18 } 19 20 int find(int x) 21 { 22 int r = x, tmp; 23 while(par[r] >= 0) r = par[r]; 24 while(x != r) 25 { 26 tmp = par[x]; 27 par[x] = r; 28 x = tmp; 29 } 30 return r; 31 } 32 33 void unio(int u, int v) 34 { 35 int ru = find(u), rv = find(v), tmp = par[ru] + par[rv]; 36 if(par[ru] < par[rv]) 37 par[rv] = ru, par[ru] = tmp; 38 else 39 par[ru] = rv, par[rv] = tmp; 40 } 41 42 void kruskal() 43 { 44 int cur = 0, u, v; 45 memset(par, -1, sizeof(par)); 46 for(int i = 1; i <= m; ++i) 47 { 48 u = e[i].u, v = e[i].v; 49 if(find(u) != find(v)) 50 { 51 ans += e[i].w; 52 unio(u, v); 53 ++cur; 54 } 55 if(cur >= n - 1) return; 56 } 57 } 58 59 int main() 60 { 61 while(~scanf("%d", &n)) 62 { 63 ans = m = 0; 64 for(int i = 1; i <= n; ++i) 65 { 66 for(int j = 1; j <= n; ++j) 67 { 68 t=read(); 69 if(j < i) e[++m].u = i, e[m].v = j, e[m].w = t; 70 } 71 } 72 sort(e + 1, e + m + 1, cmp); 73 kruskal(); 74 printf("%d ", ans); 75 } 76 return 0; 77 }
来下面解释下之前花了一阵子才理解的玩意儿TT
大部分还是很好理解的嘛,就排个序然后贪心选最短嘛,但是可能会成环,怎么办呢?当当当并查集!over!
以上都是幼儿园知识(dbq太自大了xxx我之前做的时候没有注意到略过了的才是重头戏
好的那就直接来介绍重头戏的两个函数——find&union
是的这两个函数是并查集非常经典的两个函数,但是在这里的话有了改进,具体分析见下
- 首先在kruskal函数首对fa赋初值,全部为-1(这就是第一个不一样的地方
- 接下来在find函数中 如果它爹<0,显然它还没爹,不用再找,这儿是一样的
然后如果它爹>=0,就说明它有爹了,那么它这里是用的while循环……学不来学不来xxx虽然并不太喜欢while实现的并查集但没办法,含泪学下while实现的并查集就为了不超时(哇突然感觉自己付出好多 突然戏精
- 然后进入union←这里还挺神仙代码的我觉得……还是没有很懂
这样的:……我日我感觉我好想还是没懂……我真是太傻了……dbq我再研究下明白了再写TT我真的好弱啊……好烦TT
以上是关于kruskal 最小生成树算法的主要内容,如果未能解决你的问题,请参考以下文章