C++ Kruskal算法

拈花ヽ惹草 提交于 2019-11-27 14:33:18

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;
}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!