kruskal:最小生成树
Posted qaqq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kruskal:最小生成树相关的知识,希望对你有一定的参考价值。
luogu P3366 【模板】最小生成树
在连接各个点的所有路径中,选取最短的路径连接所有点
n个顶点,e条边,时间复杂度O(eloge)
kruskal主要思路:
-
输入边,用结构体储存
-
用结构体快排以边比较从小到大快排
-
建一个并查集,并初始化并查集(并查集代表两个点有没有在同一个树里面
-
for(i=1;i<=m(边数);i++)找一条边,若其连接的两个点不在同一个并查集里面,就将两者所在的并查集合并,并将ans+=s[i].len。
-
若在同一个并查集,则跳过这次循环。因为如果这两个点连接起来,就会形成一个环。
- 直到边有n-1条
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct ll { int x,y,len; }s[200020]; bool cmp(ll a,ll b) { return a.len<b.len; } int n,m,ans; int fa[5050],big[5050]; int getfa(int x) { if(fa[x]==x) return x; return fa[x]=getfa(fa[x]); } void gaibaba(int x,int y) { int ba1=getfa(x),ba2=getfa(y); if(ba1==ba2) return; if(big[ba1]<big[ba2]) { fa[ba1]=ba2; big[ba2]+=big[ba1]; } else { fa[ba2]=ba1; big[ba1]+=big[ba2]; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].len); fa[s[i].x]=s[i].x; fa[s[i].y]=s[i].y; } int k=0; sort(s+1,s+m+1,cmp); for(int i=1;i<=m;i++) { if(getfa(s[i].x)!=getfa(s[i].y)) { ans+=s[i].len; gaibaba(s[i].x,s[i].y ); k++; } if(k==n-1) { printf("%d",ans); return 0; } } printf("orz"); return 0; }
以上是关于kruskal:最小生成树的主要内容,如果未能解决你的问题,请参考以下文章