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
*/
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章