Kruskal算法与Prim算法

(话说这么些算法的名字嗯。。。

Kruskal算法:(下文它就暂时叫k算法吧

k算法是一种应用贪心思想及并查集,在图中查找最小生成树的算法。

(最小生成树:若一个无向图内任意两个顶点联通切图为一棵树,此图即为生成树。在带权值无向图中权值和最小的生成树即为最小生成树。

时间复杂度:O(mlogm)//m为边数

算法思路

1,读入图中各个边,将所有边权值从小到大排列加入集合S;

2,将图看作一个森林,初始每个顶点都为一棵独立的树;

3,从S中取出当前最短边(u,v),若选择这条边不会与其它已选边构成回路,则选择这条边并将u,v加入已知生成树的集合中;

4,重复上述操作直到生成树集合中包含所有点。

今天勤劳的小蜜蜂整个板子题:https://www.luogu.com.cn/problem/P3366

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=5002,M=2e5+2;
 4 int n,m;
 5 int f[N],ans,cnt;
 6 struct qwq{
 7     int u,v,w;
 8 }e[M];
 9 bool cmp(qwq x,qwq y){return x.w<y.w;}
10 int getf(int x){//并查集 
11     if(f[x]==x) return x;
12     return f[x]=getf(f[x]);
13 }
14 int main(){
15     cin>>n>>m;
16     for(int i=1;i<=n;i++) f[i]=i;
17     for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w;
18     sort(e+1,e+m+1,cmp);
19     int i;
20     for(i=1;i<=m;i++){
21         int fu=getf(e[i].u),fv=getf(e[i].v);
22         if(fu==fv) continue;//若已有共同祖先,再选当前边会形成回路 
23         f[fu]=fv;
24         ans+=e[i].w;
25         cnt++;//记录连边条数 
26         if(cnt==n-1||cnt==m) break;//emm蒟蒻也不知道cnt==m是干啥的不加板子也能过 
27     }
28     if(i!=m+1) cout<<ans;
29     else cout<<"orz";
30     return 0;
31 }
复制代码

Prim算法:

Prim算法也是应用贪心思想,用于无向图中求最小生成树的算法,与k算法的区别在于Prim算法从点出发,而k算法从边出发。

时间复杂度:O(mlogn)//m为边数

算法思路:

1,任意选择一个点i,查找所有与其相连的点,选出未被标记且与i距离最小的点v,标记vis[v]=1;

2,重复上述操作直到所有点都被标记。

代码有点像迪杰斯特拉,就不注释了。。。

复制代码
#include<bits/stdc++.h>
#define ff(i,s,e) for(int i=s;i<=e;i++)
#define fir first
#define sec second
using namespace std;
inline int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
const int N=5002,M=2e5+2;
int n,m,tot,ans;
int head[N],cnt;
struct qwq{
    int v,w,nxt;
}e[M<<1];
int dis[N];
bool vis[N];
typedef pair<int,int> pir;
priority_queue<pir,vector<pir>,greater<pir> >q; 
void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
void prim(){
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    q.push(pir(0,1));
    while(!q.empty()&&tot<n){
        int d=q.top().fir,u=q.top().sec;
        q.pop();
        if(vis[u]) continue;
        tot++,ans+=d;
        vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt){
            if(e[i].w<dis[e[i].v])
                dis[e[i].v]=e[i].w,q.push(pir(dis[e[i].v],e[i].v));
        }
    }
}
int main(){
    n=read(),m=read();
    int u,v,w;
    ff(i,1,m){
        u=read(),v=read(),w=read();
        add(u,v,w);
        add(v,u,w);
    }
    prim();
    if(tot==n) printf("%d",ans);
    else printf("orz");
    return 0; 
}
复制代码

完结撒花~

posted @   专吃小仙女  阅读(169)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示