zoukankan      html  css  js  c++  java
  • krusual C++

    1.krusual算法通过边生成有权不分方向的图中最小生成树,第一点:建立一个从小到大排序的数组(Krusual的生成数组);第二点:通过集合中并操作,对新加入的边(对新加入顶点通过集合的Union操作防止产生环路)。

    #include<iostream>
    using namespace std;
    //Krusual算法的理解,依次从边中挑选出不形成回路的边形成森林
    typedef char VerterType;
    //使用邻接矩阵
    #define MAxSize 20
    int father[MAxSize],son[MAxSize];
    //father表示每一个节点的父节点
    typedef struct Graph{
        int VerterNum,edgenum;
        VerterType ver[MAxSize];
        int edge[MAxSize][MAxSize];
    
    }Graph;
    //定义一个边集结构,用来存储图上边的信息
    //存储生成图,经过排序之后的边上的图,采用集概念防止其产生回路
    typedef struct gEdge{
        int begin;
        int end;
        int weight;
        gEdge():begin(0),end(0),weight(NULL){};
    }gEdge;
    
    Graph G;
    void CreateGraph()
    {
        int VerterNum;char ver;
        cout<<"请输入顶点总数"<<endl;
        cin>>VerterNum;
        int i,j;
        memset(G.edge,0,sizeof(int)*50);
        cout<<"请输入图的顶点"<<endl;
        for(i=0;i<VerterNum;i++)
        {
            cin>>ver;
            G.ver[i]=ver;
        }
        cout<<"请输入有向图相对应的邻接矩阵"<<endl;
        int val=0;int edgenum=0;
        for(i=0;i<VerterNum;i++)
            for(j=0;j<VerterNum;j++)
            { 
                        cin>>val;
                        G.edge[i][j]=val;
                        
            }
    
            
            cout<<endl;
            //因为是有向图,
            for(i=0;i<VerterNum;i++)
            for(j=i;j<VerterNum;j++)
            {   
                        if(G.edge[i][j]!=0)
                        {    edgenum++;}
                        
            }
            //只要其上三角就行
            G.VerterNum=VerterNum;G.edgenum=edgenum;
    }
    //对数据边进行排序,产生生成图
    gEdge *CreateEdge()
    {
        //边的数组
        gEdge *p=new gEdge[G.edgenum];
        int i,j,k=0;
        for(i=0;i<G.VerterNum;i++)
            for(j=i;j<G.VerterNum;j++)
            {//选择插入排序
                if(G.edge[i][j]!=0)
                {
                    p[k].begin=i;
                    p[k].end=j;
                    p[k].weight=G.edge[i][j];
                    k++;
                
                }        
            }
            gEdge temp;
            for( i=0; i<G.edgenum-1; i++ )                  //对边集数组进行选择排序  
            for( j=i+1; j<G.edgenum; j++ )  
                if( p[i].weight > p[j].weight ) {  
                    temp = p[i];  
                    p[i] = p[j];  
                    p[j] = temp;  
                }  
      
        return p;  
    }
    
    int unionsearch(int x) //查找根结点+路径压缩  
    {  
        return x == father[x] ? x : unionsearch(father[x]);  
    }  
    bool Union(int x,int y)
    {
        int root1,root2;
        root1=unionsearch(x);
        root2=unionsearch(y);
        if(root1==root2)
        {
            return false;
        }
        else
        {
            if(son[root1]>=son[root2])
            {
                father[root2]=root1;
                son[root1]+=son[root2];//儿子接点数
            }
            else{
                father[root1]=root2;
                son[root2]+=son[root1];
            }
        }
        return true;
    }
    void Krusual()
    {
        //得到Krusual排序生成矩阵信息;
        gEdge *p=CreateEdge();
        int i ,j=0;int totalval=0;
        //没有环的矩阵
        int *MST=new int[G.edgenum];
        //使用Set中并操作,将原始是edgenum条离散的树整合成森林
        //将其初始化,开始时候每个顶点的父节点都是自己,最后形成的森林(不成环)
        for(i=0;i<G.VerterNum;i++)
        {
            father[i]=i;
            son[i]=1;
        }
        int flag[MAxSize];
        memset(flag,-1,sizeof(int)*MAxSize);
        for(i=0;i<G.edgenum;i++)
        {
            if(Union(p[i].begin,p[i].end))
            {
                totalval+=p[i].weight;
                MST[j++]=i;
                flag[i]=1;
                cout<<G.ver[p[i].begin]<<"-->"<<G.ver[p[i].end]<<endl;
            }
        }
    
        if(j==G.VerterNum-1)
        {
            cout<<totalval<<endl;
        }else
        {
            cout<<"datat error"<<endl;
        }
    }
    int main()
    {
        
        CreateGraph();
        Krusual();
        return 0;
    }

  • 相关阅读:
    【MSSQL】MSSQL还原单mdf文件报1813错误
    【JSP】JSP基础学习记录(二)—— JSP的7个动作指令
    【JSP】JSP基础学习记录(一)—— 基础介绍以及3个编译指令
    【Other】U盘FAT32转NTFS且无数据丢失
    python map()
    python关于分割与拼接的那些事
    python shutil.copy()用法
    python enumerate用法
    工作中遇到一些难题1_5
    廖雪峰读书笔记_文件读写总结_2016_12_23
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6059708.html
Copyright © 2011-2022 走看看