test

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAX 500
 using namespace std;
 struct Line{
     int start; int end; int lenth;
 }line[MAX];
 int n, linenumber, minlenth;
 int father[MAX], map[MAX][MAX], mark[MAX];
 int cmp(Line  a, Line b)
 {
     return a.lenth < b.lenth ? 1 : 0;
 }
 void initial()
 {
     int i,j;
     linenumber = 0;
     for(i = 0; i < n; i++)father[i] = i;
     for(i = 0; i < n; i++){
         for(j = i + 1; j < n; j++){
             if(map[i][j] != 0){
                line[linenumber].start = i;
                line[linenumber].end = j;
                line[linenumber++].lenth = map[i][j];
             }
         }
     }
     sort(line, line + linenumber, cmp);
 }
 int find(int k)//用并查集判断是否产生回路
 {
     return k == father[k] ? k : father[k] = find(father[k]);
 }
 void kruscal()//排序后用kruscal算法
 {
     int i, j;
     int a, b;
     minlenth = 0;
     for(i = 0, j = 0; i < linenumber; i++)
     {
         a = find(line[i].start); b = find(line[i].end);
         if(a != b)//没有产生回路,此路可用
         {
             father[a] = b;
             minlenth += line[i].lenth;
             mark[j++] = i;
         }
     }
 }
 
 void input()
 {
     int i, j;
     printf("请输入邻接矩阵:(不相连的节点间的距离视为0,节点到自身的距离也视为0)\n");
     for(i = 0; i < n; i++){
         for(j = 0; j < n; j++){
            scanf("%d", &map[i][j]);
         }
     }
 }
 void output()
 {
    int i;
    printf("最小生成树的编集为:\n");
    for(i = 0; i < n - 1; i++){
        printf("起点:%c ", line[mark[i]].start + 'a');
        printf("终点:%c ", line[mark[i]].end + 'a');
        printf("长度:%d ", line[mark[i]].lenth);
        printf("\n");
    }
    printf("最小生成树的总长度为:%d\n", minlenth);
 }
 int main()
 {
     while(cout << "请输入顶点个数:(输入0结束程序)" << endl && cin >> n && n)
     {  
         input();
         initial();
         kruscal();
         output();
     }
     if(n == 0)
         printf("程序结束!\n");
     return 0;
 }
posted @ 2012-06-01 19:42  背着超人飞  阅读(152)  评论(0)    收藏  举报