C++ Kruskal算法

kruskal与prim都是用于图的最小生成树,prim从点出发,kruskal从边出发,不同的角度解决问题,对应不同的应用场景。prim适用于点少边多的图(稠密图),kruskal 使用于边少点多的图(稀疏图),中心思想就是先排序所有边,从最小寻找两点对应的根,再把根相连,若根相同,则会成环,这在树中是不被允许的。树中的边的数目为点的数目-1,则完成最小生成树。以下代码用邻接矩阵实现,用邻接表更容易实现,我就不打邻接表的实现了,很简单


#include<iostream>  
#define MAX_VERTEX 100  
#define INFINITE 65535  
using namespace std;
//common
int _count=0;
struct Side{
	int start;
	int end;
	int weight;
};
Side* _pSide;
int vertex_parent[MAX_VERTEX];
int GetParent(int i){
	int k=vertex_parent[i]; 
	while(k!=0){
		i=k;
		k=vertex_parent[k];
		
	}
	return i;
}


//array
char vertex_infos[MAX_VERTEX];  
int matrix[MAX_VERTEX][MAX_VERTEX];  
void Tranversal_For_Side(int x,int y){

    if(vertex_infos[x]==0){  
        return ;  
    }

    for(int i=y;i<MAX_VERTEX;i++){  
        if(matrix[x][i]<INFINITE){
        	 
			_pSide[_count].start=x;
        	_pSide[_count].end=i;
        	_pSide[_count].weight=matrix[x][i];
        	_count++; 
        	
        	matrix[x][i]=INFINITE;
        	matrix[i][x]=INFINITE;
            Tranversal_For_Side(i,0);  
        }  
    }
} 


int main(){
	for(int i=0;i<MAX_VERTEX;i++){  
		vertex_parent[i]=0;
        vertex_infos[i]=0; 
        for(int j=0;j<MAX_VERTEX;j++){  
            matrix[i][j]=INFINITE;  
            matrix[i][j]=INFINITE;  
        }  
    } 
      
    cout<<"input vertex and side nums:";  
    int num_vertex;  
    int num_side;  
    cin>>num_vertex>>num_side;
    _pSide=new Side[num_side];

    cout<<"input vertex char data:";  
    for(int i=0;i<num_vertex;i++){  
        cin>>vertex_infos[i];  
    }  
      
    for(int i=0;i<num_side;i++){  
        int v1;  
        int v2;  
        int weight; 
        cout<<"input two vertex:";  
        cin>>v1>>v2;  
        cout<<"input weight:";  
        cin>>weight;  
        matrix[v1][v2]=weight; 
        matrix[v2][v1]=weight; 
    }
    //it must be connected graph
    Tranversal_For_Side(0,0);

	for(int i=_count-1;i>=0;i--){
    	bool isSwap=false;
    	for(int j=0;j<i;j++){
	    	if(_pSide[j].weight	>_pSide[j+1].weight	){
	    		swap(_pSide[j],_pSide[j+1]);
	    		isSwap=true;
	    	}
	    }
	    if(!isSwap){
    		break;
    	}
    }
    
    int count_side=0;
    int real_side=0;
    while(real_side<num_vertex-1){
    	int start=GetParent(_pSide[count_side].start);
    	int end=GetParent(_pSide[count_side].end);
    	count_side++;
    	if(start==end){
	    	continue;
	    }
    	vertex_parent[start]=end;
    	real_side++;
    }
    
  
    for(int i=0;i<num_vertex;i++){
   		cout<<i<<' '<<vertex_parent[i]<<endl;
    }
    
    delete[] _pSide;
    
    
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值