爱嘉牛LA

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Kruskal算法

1.首先将G的n个顶点看成n个孤立的连通分支,将所有的边按权从小到大排序e1,e2,e3...em

2.从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接两个不同的两同分支

3.当查看到第K条边ek=(v,w)时,若v,w分别在两个不同而连通分支T1和T2中,用边(v,w)将T1,T2连接成一个连通分支,然后继续查看k+1条边

   若v和w在当前的同一个连通分支中,就直接查看第k+1条边(既构成圈,就放弃ek)

   这个过程一直进行到之剩下一个连通分支时为止。此时,这个连通分支就是G的一颗最小生成树了

View Code
#include<iostream>
using namespace std;
struct NODE{//记录边及边的端点 
    int edge;
    int x,y;
};
int compare(const void *b1,const void *b2){
    NODE *aa=(NODE *)b1;
    NODE *bb=(NODE *)b2;
    return((aa->edge)-(bb->edge));
} 
void Kruskal(int n,int m,NODE *Edge){
    int i,j,u,v,temp1,temp2,parts=0;
    int *vertex=new int[n+1];//用vertex进行集合操作 
    qsort(Edge+1,m,sizeof(NODE),compare);
    for(i=1;i<=n;i++) 
       vertex[i]=0;//用数组vertes来进行集合操作
    for(i=1;i<=m;i++){ 
        u=Edge[i].x;
        v=Edge[i].y;//第i条边的端点u,v 
        if(!vertex[u]&&!vertex[v]){
            parts++;//增加一个分支 
            vertex[u]=parts;//添加边u 
            vertex[v]=parts;//添加边v
            cout<<u<<" "<<v<<endl; 
        } 
        else
           if(vertex[u]&&!vertex[v]){//如果点u已处理而点v未处理原始状态 
               parts++;//增加一分支 
               vertex[v]=vertex[u];//将变(u,v) 加入到v所在的支 
               cout<<u<<" "<<v<<endl;
           }
           else
           if(!vertex[u]&&vertex[v]){// 如果点v已处理而点u未处理原始状态 
              parts++;
              vertex[u]=vertex[v];
              cout<<u<<" "<<v<<endl;
           }
           else
              if(vertex[u]!=vertex[v]){//如果u和v处于不同的支 
            cout<<u<<" "<<v<<endl;
            temp1=vertex[u];
            temp2=vertex[v];
            if(vertex[u]>vertex[v]){
                temp1=vertex[v];
                temp2=vertex[u];
            } 
            for(j=1;j<=m;j++){
                if(vertex[j]==temp2)//缩小,调整到较小标号的支 
                   vertex[j]=temp1;
                else 
                  if(vertex[j]>temp1)
                   vertex[j]--;
            }
            parts--;//分支数减少1 
           }
    } 
    delete vertex;
    
}
int main(){
    int n,m;
    int i;
    NODE *Edge;
    cout<<"请输入顶点个数和边数:"; 
    cin>>n>>m;
        Edge=new NODE[m+1];
        cout<<"两顶点的序号和连接他们的边的权值:"<<endl;
        for(i=1;i<=m;i++)
            cin>>Edge[i].x>>Edge[i].y>>Edge[i].edge;
            
        cout<<"最小生成树连接情况:"<<endl;
        Kruskal(n,m,Edge);
        delete Edge;
  
    return 0;
}

 

posted on 2012-11-10 09:43  爱嘉牛LA  阅读(264)  评论(0编辑  收藏  举报