【模板】最小生成树

kruskal算法

O ( m l o g m ) O(mlogm) O(mlogm)

#include<bits/stdc++.h> using namespace std; const int N=10005; struct rec{ int x,y,z; }e[N]; bool operator <(rec a,rec b) { return a.z<b.z; } void read(int &x) { int f=1;x=0;char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();} x*=f; } int n,m,fa[N]; long long ans; int find(int x) { if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void kruskal() { sort(e+1,e+m+1); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) { int x=e[i].x,y=e[i].y,z=e[i].z; int u=find(x),v=find(y); if(u!=v) { fa[x]=y; ans+=e[i].z; } } } int main() { read(n),read(m); for(int i=1;i<=m;i++) { read(e[i].x),read(e[i].y),read(e[i].z); } kruskal(); printf("%lld",ans); }

prim算法

O ( n 2 ) O(n^2) O(n2)

#include<bits/stdc++.h> using namespace std; const int N=105; void read(int &x) { int f=1;x=0;char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();} x*=f; } int n,d[N],a[N][N],ans; bool v[N]; void prim() { memset(d,0x3f,sizeof(d)); memset(v,0,sizeof(v)); 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; } v[x]=1; for(int y=1;y<=n;y++) { if(!v[y]) d[y]=min(d[y],a[x][y]); } } } int main() { read(n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { read(a[i][j]); } } prim(); for(int i=1;i<=n;i++) ans+=d[i]; printf("%d",ans); }

eg.北极网络

分析:本题肯定和最小生成树有关,给了k个通信卫星,这k个点是不用与其他点联通的。仿照 k r u s k a l kruskal kruskal算法,依次考虑最短的边,同时记录当前的连通块数量。若 x = y x=y x=y,则跳过;否则,令 t o t − − tot-- tot.若 t o t = k tot=k tot=k,说明剩下的点可以用通信卫星连接,直接输出当前边的长度,就是最小的d值。
证明如下:若连接当前最短的边,对后面的边最多只有一个边无法被选择(因为只占用了一个点),而这个当前最短的边显然是比后面的边更优的。整个思想是贪心。

#include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn=505*505; struct rec{ int x,y; double z; }edge[maxn]; bool operator <(rec a,rec b) { return a.z<b.z; } void read(int &x) { int f=1;x=0;char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();} x*=f; } int k,n,m,fa[maxn],xi[maxn],yi[maxn],tot,index; double f[maxn]; int get(int x) { if(fa[x]!=x) fa[x]=get(fa[x]); return fa[x]; } int main() { int t=1; //read(t); while(t--) { m=index=0; read(n),read(k); for(int i=1;i<=n;i++) { read(xi[i]),read(yi[i]); for(int j=1;j<i;j++) { edge[++m].z=sqrt(1.0*(xi[i]-xi[j])*(xi[i]-xi[j])+1.0*(yi[i]-yi[j])*(yi[i]-yi[j])); edge[m].x=i; edge[m].y=j; } } sort(edge+1,edge+m+1); for(int i=1;i<=n;i++) fa[i]=i; tot=n; if(tot<=k) { printf("0.00\n"); continue; } for(int i=1;i<=m;i++) { int x=get(edge[i].x); int y=get(edge[i].y); if(x==y) continue; fa[x]=y; tot--; if(tot==k) { printf("%.2lf\n",edge[i].z); break; } } } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530409.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示