最小生成树

题目链接

P3366 【模板】最小生成树


【模板】最小生成树

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz。

输入格式

第一行包含两个整数 N,M,表示该图共有 N 个结点和 M 条无向边。

接下来 M 行每行包含三个整数 Xi,Yi,Zi ,表示有一条长度为 Zi 的无向边连接结点 Xi,Yi

输出格式

如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz。

输入

4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3

输出

7

说明/提示

数据规模:

对于 20% 的数据,N5M20

对于 40% 的数据,N50M2500

对于 70% 的数据,N500M104

对于 100% 的数据:N50001M2×1051Zi104

prim

  • 时间复杂度:O(n2)

代码

#include<bits/stdc++.h> using namespace std; const int N=5005,inf=0x3f3f3f3f; int a[N][N]; int d[N]; bool v[N]; int n,m; int prim() { memset(d,0x3f,sizeof d); int res=0; d[1]=0; for(int i=1;i<=n;i++) { int x=0; for(int j=1;j<=n;j++) if(!v[j]&&(x==0||d[j]<d[x]))x=j; if(d[x]==inf)return inf; v[x]=true; res+=d[x]; for(int j=1;j<=n;j++) d[j]=min(d[j],a[x][j]); } return res; } int main() { memset(a,0x3f,sizeof a); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)a[i][i]=0; while(m--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); a[x][y]=a[y][x]=min(a[x][y],z); } int res=prim(); if(res==inf) puts("orz"); else printf("%d",res); return 0; }

kruskal

  • 时间复杂度:O(mlogm)

代码

#include<bits/stdc++.h> using namespace std; const int N=5005,M=2e5+10; struct rec { int x,y,z; bool operator<(rec &other) { return z<other.z; } }edge[M]; int fa[N]; int n,m,s,cnt; int res; bool v[N]; int get(int x) { if(x==fa[x])return x; return fa[x]=get(fa[x]); } void kruskal() { sort(edge,edge+m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=0;i<m;i++) { int x=get(edge[i].x),y=get(edge[i].y),w=edge[i].z; if(x==y)continue; cnt++; res+=w; fa[x]=y; } } int main() { scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z); v[edge[i].x]=v[edge[i].y]=true; } kruskal(); if(cnt==n-1) printf("%d",res); else puts("orz"); return 0; }

Borůvka

相当于多源 prim 算法,即多个连通块同时扩展连向其他连通块的最小边,由于是所有连通块同时进行的,所以每次连通块的合并会大概有一半的连通块减少,即整个连通块的合并操作有 O(logn) 次,同时注意可能会有两个连通块选择了同一条边,需要标记防止重边,同时还可能出现环的情况,合并时判断是否在一个连通块内即可

  • 时间复杂度:O(mlogn)

代码

// Problem: P3366 【模板】最小生成树 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P3366 // Memory Limit: 128 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=5005,M=2e5+5; int n,m,fa[N],chosen[N]; bool used[M]; struct { int x,y,w; }a[M]; int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } void boruvka() { bool update=true; int res=0,merged=0; while(update) { update=false; for(int i=1;i<=n;i++)chosen[i]=0; for(int i=1;i<=m;i++) { if(used[i])continue; int x=a[i].x,y=a[i].y,w=a[i].w; x=find(x),y=find(y); if(x==y)continue; if(chosen[x]==0||a[chosen[x]].w>w)chosen[x]=i; if(chosen[y]==0||a[chosen[y]].w>w)chosen[y]=i; } for(int i=1;i<=n;i++) { if(!chosen[i])continue; int x=find(a[chosen[i]].x),y=find(a[chosen[i]].y); if(used[chosen[i]]||x==y)continue; used[chosen[i]]=true; update=true; merged++; fa[x]=y; res+=a[chosen[i]].w; } } if(merged>=n-1)printf("%d\n",res); else puts("orz"); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); for(int i=1;i<=n;i++)fa[i]=i; boruvka(); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15306334.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(51)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示