Kruskal算法

#include < iostream .h >
const int n=6;  //图的顶点数
const int e=10;  //图的边数 n-1=
< e < =n(n-1)/2 
typedef int adjmatrix[n][n];  
typedef struct{           //生成树的边结点
    int fromvex,endvex;    //边的起点与终点
    int weight;           //边上的权
}TreeEdgeNode;
typedef TreeEdgeNode edgesetT[n-1];  //这是不
typedef TreeEdgeNode edgesetG[e];

void Kruskal(edgesetG GE,edgesetT CT,int n)
//利用克鲁斯卡尔算法求边集数组GE所示图的最小生成树,
//树中每条边依次存于数组C中
{
    int i,j;
    adjmatrix s;//用二维数组s作为集合使用,其中每一行元素
           //s[i][0]~s[i][n-1]用来表示一个集合,若s[i][t]
==1
           
//则表示v[t]顶点属于该集合,否则不属于s[i]集合
    for(i
=0;i<n;i++)
    
{  //初始化s集合,使每一个顶点分属于不同的集合 
        for(j
=0;j<n;j++)
            
if(i ==j)
                
s[i][j] =1;
            
else
                s[i][j]
=0;
    
}//循环执行结束后,使得v[i]顶点属于s[i]集合中
    int k
=1;//k表示待获取的最小生成树中的边数,初值为1
    
int d =0;//d表示GE中待扫描边元素的下标位置,初值为0
    
int m1,m2;//m1和m2用来分别记录一条边的两个顶点所在的集合的序号
    while(k<n)
    {//进行n-1次循环,得到最小生成树中的n-1条边
        /*for(i
=0;i<n;i++)
        
{//求出边GE[d]的两个顶点所在集合的序号m1和m2]
            for(j
=0;j<n;j++)
            
{
                if(GE[d].fromvex
==j&&s[i][j]==1)//找起点
                    
m1 =i;
                
if(GE[d].endvex ==j&&s[i][j]==1)//找终点
                    
m2 =i;
            
}

        }*/
       //可以把上面的重for循环改良成如下的一重for循环
        for(i
=0;i<n;i++)
        
{
            if(s[i][GE[d].fromvex]
==1)//找起点
                    
m1 =i;
            
if(s[i][GE[d].endvex] ==1)//找终点
                    
m2 =i;
        
}
        if(m1!
=m2)
        
{   //若两集合序号不等,则表明GE[d]是生成树中的一条边,
            //应将它加入到数组C中
            CT[k-1]
=GE[d];
            
//cout<<"CT[<<k-1<<] =<<CT[k-1].
            
k++;
            for(j
=0;j<n;j++)
            
{//合并两个集合,并将另一个置为空集
                s[m1][j]
=s[m1][j]||s[m2][j];
                
s[m2][j] =0;
            
}
        }
        d++;//d后移一个位置,以便扫描GE中的下一条边
    }

}
void main()
{
    int i;
    edgesetG GE;
    edgesetT CT;
    cout<<"请按权值小到大输入边集:"<<endl;
    for(i
=0;i<e;i++)//这是不妥的,因为不知道到底有多少边
    
{
        cin
> >GE[i].fromvex>>GE[i].endvex>>GE[i].weight;
    }
    Kruskal(GE,CT,n);
    cout
< <"最上生成树的边集为: "<<endl;
    for(i
=0;i<n-1;i++)
    
{
        cout<<CT[i].fromvex<<"  "<<CT[i].endvex<<"  "<<CT[i].weight<<endl;
    }

}
/*测试用例一:
请按权值小到大输入边集:
0 4 4
1 2 5
1 3 8
2 3 10
1 5 12
3 5 15
0 1 18
3 4 20
0 5 23
4 5 25
最上生成树的边集为:
0  4  4
1  2  5
1  3  8
1  5  12
0  1  18
*/
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值