您的位置:首页 > 编程语言 > C语言/C++

最小生成树的Kruskal算法(C/C++)--附有测试数据和结果

2010-04-29 18:26 453 查看
/*
 *算法原理:将图G 中的边按权数从小到大逐条考察,
 *     按不构成圈的原则加入到T中(若有选择时, 不同的选
 *     择可能会导致最后生成树的权数不同), 直到
 *     q(T) = p(G)-1为止, 即 T 的边数 = G 的顶点1 为止.
 *算法中无圈性的判定比较麻烦,应该用标记法最好,
 *对各个分支的顶点标号。
 *我没仔细看书,其实书上写得很清楚,是老师提醒的 ^_^ 。
 *参考书:2004,《图论及其应用》,科学出版社,孙惠泉 编著。
 */
#include<iostream>
#include<fstream>
#define N 100
using namespace std;
int n;//结点数
int a

 = {0};
bool judgeNode(int flagNodes
){//判断是否还有未访问结点
    for(int i = 0; i < n; i++)
        if(flagNodes[i] == 0) return 1;
    return 0;
}
void judgeSub(int flagSub
, int x, int y){//标记分支
    if(flagSub[x] != 0){
        if(flagSub[y] == 0) flagSub[y] = flagSub[x];
        else{
            int min = flagSub[x] < flagSub[y] ? flagSub[x] : flagSub[y];
            int max = flagSub[x] + flagSub[y] - min;
            for(int i = 0; i < n; i++)
                if(flagSub[i] == max)
                    flagSub[i] = min;
        }
    }
    else{
        if(flagSub[y] == 0){
            int max = 0;
            for(int i = 0; i < n; i++){
                if(flagSub[i] != 0 && flagSub[i] > max)
                    max = flagSub[i];
            }
            flagSub[x] = flagSub[y] = ++max;
        }
        else flagSub[x] = flagSub[y];
    }
}
bool judgeCircle(int flagSub
, int x, int y){//判断生成树中无圈
    if(flagSub[x] == 0 && flagSub[y] == 0) return 1;
    if(flagSub[x] != flagSub[y]) return 1;
    return 0;
}
void kruskal(){
    int temp

 = {0};
    int flagNodes
 = {0};
    int flagSub
 = {0};
    int least = N;
    int x = 0, y = 0;
    cout<<"The edges of Optimal tree:"<<endl;
    while(judgeNode(flagNodes)){
        least = N;
        for(int i = 0; i < n; i++){
            for(int j = i+1; j < n; j++){
                if(a[i][j] && a[i][j] < least && //关键的判断条件
                        judgeCircle(flagSub, i, j) && temp[i][j]==0){
                    least = a[i][j];
                    x = i, y = j;
                }
            }
        }
        cout<<"("<<x<<","<<y<<")-";//输出选取人权值最小的边
        if(least < N){
            flagNodes[x] = 1;
            flagNodes[y] = 1;
            judgeSub(flagSub, x, y);
            temp[x][y] = 1, temp[y][x] = 1;
        }
    }
    cout<<endl;
    //onput optimal tree
    cout<<"Optimal Tree in the Matrix:"<<endl;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++)
            cout<<temp[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}
int main(){
    ifstream in("kruskal.txt");
    int nodes,entry;
    while(in>>n){
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                in>>a[i][j];
        kruskal();//Kruskal函数
    }
    return 0;
}
/*
////测试数据(kruskal.txt):
8
0 2 8 1 0 0 0 0
2 0 6 0 1 0 0 0
8 6 0 7 5 1 2 0
1 0 7 0 0 0 9 0
0 1 5 0 0 3 0 8
0 0 1 0 3 0 4 6
0 0 2 9 0 4 0 3
0 0 0 0 8 6 3 0
6
0 3 3 0 5 0
3 0 3 1 1 4
3 3 0 4 4 0
0 1 4 0 0 2
5 1 4 0 0 2
0 4 0 2 2 0
////测试结果:
The edges of Optimal tree:
(0,3)-(1,4)-(2,5)-(0,1)-(2,6)-(4,5)-(6,7)-
Optimal Tree in the Matrix:
0 1 0 1 0 0 0 0
1 0 0 0 1 0 0 0
0 0 0 0 0 1 1 0
1 0 0 0 0 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 1 0 0 0
0 0 1 0 0 0 0 1
0 0 0 0 0 0 1 0
The edges of Optimal tree:
(1,3)-(1,4)-(3,5)-(0,1)-(0,2)-
Optimal Tree in the Matrix:
0 1 1 0 0 0
1 0 0 1 1 0
1 0 0 0 0 0
0 1 0 0 0 1
0 1 0 0 0 0
0 0 0 1 0 0
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: