AcWing算法提高课 最小生成树
一般使用kruskal(克鲁斯卡尔)(mlogm)
对于稀疏图,用朴素prim(n^2)
prim:每次选择和当前已经构建出的连通块相连,且权重最小的边,加入当前连通块。
一共需要扩展(n-1)次
只能处理一个连通块,不能“生成森林”
例题:https://www.acwing.com/problem/content/1142/
模板:

int n; const int N=110; int adj[N][N]; int dis[N]; bool st[N]; int Prim() { int res=0; memset(dis,0x3f,sizeof(dis)); dis[1]=0; for(int i=0;i<n;i++) { int t=-1; for(int j=1;j<=n;j++) { if(!st[j]&&(t==-1||dis[t]>dis[j])) { t=j; } } res+=dis[t]; st[t]=true; for(int j=1;j<=n;j++) { dis[j]=min(dis[j],adj[t][j]); } } return res; }
kruskal:基于并查集。先将所有边从小到大排序,然后枚举每条边,如果边的两个端点还不联通,则将当前边加入最小生成树。
例题:
https://www.acwing.com/problem/content/1143/
模板:

vector<PIII> edges; int p[N]; int find(int x) { if(p[x]!=x) p[x]=find(p[x]); return p[x]; } void merge(int a,int b) { int pa=find(a); int pb=find(b); p[pa]=pb; } void Kruskal() { fore(i,1,n) p[i]=i; sort(edges.begin(),edges.end()); for(auto edge:edges) { int a=edge.se.fi; int b=edge.se.se; int pa=find(a); int pb=find(b); if(pa!=pb) { //record edge merge(a,b); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人