zoukankan      html  css  js  c++  java
  • Minimum Spanning Tree.prim/kruskal(并查集)

    开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可)

    prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图

    #include<iostream>              //prim  n^2
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int a[102][102];int dis[102];int mark[102];
    int main()
    {
        int n;
        while(cin>>n&&n)
        {
            int m=n*(n-1)/2;
            int x,y;
            memset(a,0x3f,sizeof(a));
            memset(dis,0x3f,sizeof(dis));
            memset(mark,0,sizeof(mark));
            while(m--)
            {
               scanf("%d%d",&x,&y);
               int temp;
               scanf("%d",&temp);
               if(a[x][y]>temp)
                 a[x][y]=temp;
              a[y][x]=a[x][y];
            }
            int ans=0;
            int cur=1;
            mark[cur]=1;
            for(int i=1;i<n;i++)               //加入n-1条边
            {
              int minedge=inf; int vertex;     //每次找最小的边和新加入的点
                for(int j=1;j<=n;j++)
                  if(mark[j]==0)
                {
                    if(dis[j]>a[cur][j])      //更新
                    {
                        dis[j]=a[cur][j];
                    }
                    if(minedge>dis[j])        //得最小边
                   {
                     minedge=dis[j];
                     vertex=j;
                   }
                 }
                 ans+=minedge;
                 cur=vertex;            //新加入的点cur
                 mark[cur]=1;          //已经加入
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    #include<iostream>        //kruskal ,+并查集维护,m*logm
    #include<vector>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int fa[102];                 
    int father(int x){return (x==fa[x]?x:father(fa[x]));}
    struct edge                
    {
        int x,y,w;
    };
    bool my(const edge &a,const edge &b)       //先按权重排序
    {
        return a.w<b.w;
    }
    int main()
    {
         int n;
        while(cin>>n&&n)
        {
            int m=n*(n-1)/2;
            vector<edge>v(m);
            for(int i=1;i<=n;i++)          //初始化并查集
               fa[i]=i;
           for(int i=0;i<m;i++)
           {
              scanf("%d%d",&v[i].x,&v[i].y);
              int temp;
              scanf("%d",&temp);
              v[i].w=temp;
            }                            
            int ans=0;
            sort(v.begin(),v.end(),my);    //排序
            for(int i=0,num=0;num<n-1;i++)      //取
            {
                int xx=father(v[i].x);int yy=father(v[i].y);
                if(xx!=yy)                  //不是同一个连通分量,合并之
                {
                    ans+=v[i].w;
                    fa[xx]=yy;
                    num++;                      //发现一个有效边,共n-1条。
                }
            }
            printf("%d
    ",ans);
        }
      return 0;
    }
    

    #include<iostream>                 //求无向图连通分支数,直接并查集。
    #include<vector>
    #include<algorithm>
    #include<cstdio>
    #include<set>
    using namespace std;
    int fa[1002];
    int father(int x){return (x==fa[x]?x:father(fa[x]));}
    struct edge
    {
        int x,y;
    };
    int main()
    {
        int n,m;
        while(~scanf("%d",&n)&&n)
        {
            scanf("%d",&m);
            vector<edge>v(m);
            for(int i=1;i<=n;i++)
             {
                 fa[i]=i;                //初始化
             }
            for(int i=0;i<m;i++)
            {
              scanf("%d%d",&v[i].x,&v[i].y);
            }
    
            for(int i=0;i<m;i++)
            {
                int xx=father(v[i].x);     //x--y有边。
                int yy=father(v[i].y);
                fa[xx]=yy;
            }
            int count=0;
            set<int>se;
            for(int i=1;i<=n;i++)      //只需看有几个father(i)(等价类),一个连通分量只对应一个。
            {
                se.insert(father(i));
            }
            count=se.size()-1;
            printf("%d
    ",count);
        }
        return 0;
    }
    


  • 相关阅读:
    php知识点
    CommonsChunkPlugin知识点
    待学习
    svn知识点
    es6知识点
    webpack2新特性
    排序算法
    交流措辞
    js继承
    多行编辑软件
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925753.html
Copyright © 2011-2022 走看看