zoukankan      html  css  js  c++  java
  • 最小生成树Kruskal算法

    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;
    }
  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/aijianiula/p/2763722.html
Copyright © 2011-2022 走看看