最小生成树(大纲,待补全)

最小生成树

最小生成树 - OI Wiki

前置知识#

生成树

最小生成树

Prim#

不常用(又不如kruskal快又不如kruskal好写),了解即可

思路类似dijkstra

以下为我也不知道我啥时候写出来的代码

邻接矩阵版本

Copy
#include <bits/stdc++.h> using namespace std; int n, m; int t[5001][5001]; int d[5001]; bool vis[5001]; int ans, cnt; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) t[i][j] = 1000000005; t[i][i] = 0; } for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; t[v][u] = t[u][v] = min(t[u][v], w); } for (int i = 1; i <= n; i++) { d[i] = 1000000005; } for (int i = 1; i <= n; i++) { d[i] = t[1][i]; } d[1] = 0; vis[1] = 1; while (cnt <= n - 1) { int mini = 0, mind = 1000000005; for (int i = 1; i <= n; i++) { if (!vis[i] && d[i] < mind) { mind = d[i]; mini = i; } } if (mini == 0) { break; } cnt++; ans += mind; d[mini] = 0; vis[mini] = 1; for (int i = 1; i <= n; i++) { d[i] = min(d[i], t[mini][i]); } } if (cnt == n - 1) { cout << ans << endl; } else { cout << -1 << endl; } }

邻接表版本

Copy
#include <bits/stdc++.h> using namespace std; int n, m; int fir[200001], to[1000001], nxt[1000001], dis[1000001], ecnt; void add(int u, int v, int w) { to[++ecnt] = v; dis[ecnt] = w; nxt[ecnt] = fir[u]; fir[u] = ecnt; } int d[200001]; bool vis[200001]; int cnt; long long ans; struct node { int x, d; node(int x, int d) : x(x), d(d) {} }; bool operator<(node a, node b) { return a.d > b.d; } priority_queue<node> q; int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; add(u, v, w); add(v, u, w); } for (int i = 1; i <= n; i++) d[i] = 1000000005; q.push(node(1, 0)); d[1] = 0; cnt = -1; while (!q.empty() && cnt < n - 1) { node h = q.top(); q.pop(); if (vis[h.x]) continue; vis[h.x] = 1; d[h.x] = 0; cnt++; ans += h.d; for (int e = fir[h.x]; e; e = nxt[e]) { if (d[to[e]] > dis[e]) { d[to[e]] = dis[e]; q.push(node(to[e], d[to[e]])); } } } if (cnt == n - 1) { cout << ans << endl; } else { cout << "orz" << endl; } }

Kruskal#

思想:贪心

每次找一条最短的边往生成树里加

正确性#

Kruskal 证明 - OI Wiki

待补充

代码#

Copy
#include<bits/stdc++.h> using namespace std; struct edge{ int from,to,dis; }g[500001]; bool cmp(edge a,edge b){ return a.dis<b.dis; } int fa[200001]; int getf(int x){ if(fa[x]==x)return x; fa[x]=getf(fa[x]); return fa[x]; } int n,m,cnt; long long ans; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ cin>>g[i].from>>g[i].to>>g[i].dis; } for(int i=1;i<=n;i++){ fa[i]=i; } sort(g+1,g+m+1,cmp); for(int i=1;i<=m&&cnt<n-1;i++){ int fu=getf(g[i].from),fv=getf(g[i].to); if(fu==fv)continue; fa[fu]=fv; cnt++; ans+=g[i].dis; } if(cnt==n-1){ cout<<ans<<endl; }else{ cout<<"orz"; } }

讲到的题#

U69308 【常数PK系列】 #3 最小生成树

P1550 [USACO08OCT]Watering Hole G

P1536 村村通

P1396 营救

[P2820 局域网](https://www.luogu.com.cn/problem/P2820

posted @   water_lift  阅读(152)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
CONTENTS