(Day8)算法复健运动for蓝桥杯-最小生成树
(Day8)算法复健运动for蓝桥杯-最小生成树
一提到生成树就是经典prim和kruskal,一个从一个点开始,一个把边排序
虽然不用反复造轮子,但是还是需要从算法思想直接写出来,不能老背板子
练手的模板题:
https://www.luogu.com.cn/problem/P3366
kruskal好写一些,先写这个
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+9;
int rt[N];
struct node
{
int x,y,z;
}a[N];
bool cmp(node a,node b)
{
return a.z<b.z;
}
int fin(int x)
{
if(rt[x]==x)return x;
return rt[x]=fin(rt[x]);
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)rt[i]=i;
for(int i=1;i<=m;i++)
{
cin>>a[i].x>>a[i].y>>a[i].z;
}
sort(a+1,a+1+m,cmp);
int sum=0,num=0;
for(int i=1;i<=m;i++)
{
int xx = fin(a[i].x);
int yy = fin(a[i].y);
if(xx!=yy)
{
rt[xx]=yy;
sum+=a[i].z;
num++;
}
if(num>=n-1)break;
}
if(num<n-1)cout<<"orz"<<endl;
else cout<<sum<<endl;
return 0;
}
prim算法
原理就是开始只有1在点集里面,然后找1连通的所有点,选最小的边,然后把这条边对应的点加入点集,然后找点集里面所有点连通的边最小的,加入点。再找整个点集所有点。。。
一般使用邻接矩阵存图
时间复杂度:o(n^2)
模板:
#include<bits/stdc++.h>
#define inf 1e9
using namespace std;
const int N=1e3+9;
int mp[N][N];
int low[N],vis[N];
int main()
{
memset(vis,0,sizeof(vis));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",mp[i][j]);
if(mp[i][j]==-1)mp[i][j]=inf;//没有边
}
}
for(int i=1;i<=n;i++)//每个点与1的距离
{
low[i]=mp[i][1];//low数组是一维的,为什么呢,就是因为它存储的是每个点和点集的距离最小值,不是指哪个点
}
int ans=0;
vis[1]=1;
for(int i=1;i<=n-1;i++)//一共n-1条边
{
int minn=inf;
int pos;
for(int j=1;j<=n;j++)//如果一个点不在树里而且离点集最小
{
if(low[j]<minn&&!vis[j])
{
minn=low[j];
pos=j;
}
}
ans+=minn;
vis[pos]=1;
for(int j=1;j<=n;j++)//更新low数组
{
if(mp[pos][j]<low[j])
{
low[j]=mp[pos][j];
}
}
}
printf("%d\n",ans);
return 0;
}
分类:
ACM / 数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义