• 最小生成树算法及模板


    最小生成树算法分为

    1.prime算法 O(n^2)

       由点到边,每次将到集合距离最短的集合外的点加入集合中,在松弛集合外的点到集合的距离;

    2.kruskal 0(mlogm)

    将边从小到大排序,循环每一条边,如果两点未在同一集合里(并查集维护),则将该边加入集合中;

    稠密图用prime,稀疏图用kruskal

    prime

    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int INF=0x3f3f3f3f;
    int n,m;
    int g[510][510];
    int dist[510];int vis[510];
    int prime()
    {
        memset(dist,0x3f,sizeof dist);
        int res=0;
        for(int i=0;i<n;i++)//迭代n次
        {
            int t=-1;
            for(int j=1;j<=n;j++)
            if(!vis[j]&&(t==-1||dist[t]>dist[j]))
            t=j;
            if(i&&dist[t]==INF)
            return INF;//i如果不是第一个迭代且已经不存在最短边,则最小生成树不存在;‘
            if(i)res+=dist[t];//如果不是第一次迭代则加入最小生成树的值
            for(int j=1;j<=n;j++)dist[j]=min(dist[j],g[t][j]);//松弛到集合的距离
            vis[t]=1;
        }
        return res;
    }
    int main()
    {
        memset(g,0x3f,sizeof g);
        cin>>n>>m;
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a][b]=min(g[a][b],c);
            g[b][a]=min(g[b][a],c);
        }
        int t=prime();
        if(t==0x3f3f3f3f)printf("impossible
    ");
        else
        printf("%d
    ",t);
        return 0;
    }

    kruskal()

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m;
    int p[200010];
    struct node
    {
        int a,b,w;
        bool operator <(node &y)const
        {
            return  w<y.w;
        }
    }edge[200010];
    int find(int x)
    {
        if(p[x]==x)return x;
        else
        return p[x]=find(p[x]);
    }
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w);
        }
        sort(edge,edge+m);
        for(int i=1;i<=n;i++)
         p[i]=i;int res=0,cnt=0;//cnt存加入集合的边数
         for(int i=0;i<m;i++)//对每一条边操作
         {
             int a=edge[i].a,b=edge[i].b,w=edge[i].w;
             a=find(a),b=find(b);
             if(a!=b)
             res+=w,p[a]=b,cnt++;
         }
         if(cnt<n-1)printf("impossible
    ");
         else
         printf("%d
    ",res);
        return 0;
    }
  • 相关阅读:
    VMware 虚拟机NAT模式如何设置网络连接,从头到尾全过程~!!
    mysql数据库中的索引介绍与优化(转)
    AWS磁盘容量问题
    Shell实现强制释放内存
    Tomcat #无法启动8005端口
    100个命令Linux常用命令大全
    Keepalived+Nginx实现高可用负载均衡集群
    python 备份压缩传输
    Python 数据库备份脚本
    shell自动化巡检
  • 原文地址:https://www.cnblogs.com/flyljz/p/11766259.html
Copyright © 2020-2023  润新知