有个最小生成树的code

转载别人写的代码。

有个最小生成树的code:

#include  < cstdio >
#include 
< cstdlib >


#define  MAX 65535

typedef 
struct   bool     same;
    
int         m_iPoint;
}Same;

typedef 
struct  Edge         // 边的数据结构;            
{
    
int        m_iPoint1;    //边的端点
    int        m_iPoint2;    //边的端点
    int        key;        //边的权值
    bool    bFind;        //标记是否被选中;
}
 Edge;

//
// 数组s用来保存顶点的数值;s【0】中记录数组个数;顶点数组;
// iCount有何作用:记录顶点的数目;
//
void  InputData( Edge *  lLine,  int  n,  int   & iCount )             // 初始化数据
{
    
int Vertex[31];
    Vertex[
0= 0;
    
bool IsSame[2];

    
for ( int i = 0; i < n ; i++)                            //利用循环读入数据
    {
        printf(
"----------------------------------- ");
        printf(
"input the begin : ");
        scanf(
"%d"&lLine[i].m_iPoint1);
        printf(
"input the end : ");
        scanf(
"%d"&lLine[i].m_iPoint2);
        printf(
"input the  fly time: ");
        scanf(
"%d"&lLine[i].key);
        printf(
"----------------------------------- ");
        
int t;
        
        
//始终边的端点有序性:iPoint1 < iPoint2
        if ( lLine[i].m_iPoint1 > lLine[i].m_iPoint2 )             
        
{
            t 
= lLine[i].m_iPoint2;
            lLine[i].m_iPoint2 
= lLine[i].m_iPoint1;
            lLine[i].m_iPoint1 
= t;
        }

        
//初始化标志变量;
        lLine[i].bFind = false;

        IsSame[
0= false;
        IsSame[
1= false;
    
        
for (int j = 1; j <= Vertex[0]+1; j++)                    //判断元素个数
        {
            
if ( Vertex[j] == lLine[i].m_iPoint1 )
                IsSame[
0= true;
            
if ( Vertex[j] == lLine[i].m_iPoint2 )
                IsSame[
1= true;
        }

        
//通过边的输入来实现对顶点的提取;
        
//把没有出现过的顶点放入数组:s中;
        if (!IsSame[0])
        
{
            Vertex[
0]++;
            Vertex[Vertex[
0]] = lLine[i].m_iPoint1;
        }

        
if (!IsSame[1])
        
{
            Vertex[
0]++;
            Vertex[Vertex[
0]] = lLine[i].m_iPoint2;
        }

    }

    iCount 
= Vertex[0];
}


//
// n表示边的数目;
// count表示顶点的数目;
// lLineEn保存最小生成树的边;
// lLineUn保存所有的边
//
void  MiniTree(Edge  * lLineUn, Edge  * lLineEn,  int  n,  int  count)     // 生成最小生成树
{
    
//里面将要存放顶点;
    int Vertex[31] ;
    
for ( int i = 0; i < n+1; i++)
    
{
        Vertex[i] 
= 0;
    }


    
int set[31];        //set与iPoint同步的;
    for (i = 0; i < 31; i++)
        
set[i] = i;

    
int        iCount = 0;
    
int        iMini;        //iMini保存的最小的key值
    int        iMinii;        //iMinii保存的最小的index下标;

    
//最小生成树:边数 = 顶点数-1;
    while ( iCount < (count - 1) )
    
{
        Same s[
2];
        
int d, j;
        iMini 
= MAX;
        
//n表示边的个数;
        
//每次重剩余的中间查找最小的边
        for ( j = 0; j < n; j++)                                
        
{
            
//重没有被选中的边中查找;
            if ( (lLineUn[j].key < iMini) && (!lLineUn[j].bFind) )
            
{
                iMini 
= lLineUn[j].key;
                
//最小边的下标;
                iMinii = j;
            }

        }

        
//将最小边的标志置为true
        lLineUn[iMinii].bFind = true;

        
//判断已生成最小生成树中的元素个数
        
//寻找最小边的顶点是否已经存在;
        s[0].same = false;                                        
        d 
= 0;
        
for ( j = 1; (j < Vertex[0]+1&& !s[0].same; j++)
        
{
            
if ( lLineUn[iMinii].m_iPoint1 == Vertex[j] )
            
{
                s[
0].same = true;
            }

        }

        
if (!s[0].same)
        
{
            s[
0].m_iPoint = lLineUn[iMinii].m_iPoint1;
            d
++;
        }

        
        s[
1].same = false;
        
for ( j = 1; (j < Vertex[0]+1&& !s[1].same; j++)
        
{
            
if ( lLineUn[iMinii].m_iPoint2 == Vertex[j] )
            
{
                s[
1].same = true;
            }

        }

        
if (!s[1].same)
        
{
            s[
1].m_iPoint = lLineUn[iMinii].m_iPoint2;
            d
++;
        }

        
//二者会相等吗?估计下面set会被修改过的
        
//判断是否构成环路
        //
        if ( set[lLineUn[iMinii].m_iPoint1] != set[lLineUn[iMinii].m_iPoint2])    
        
{
            iCount
++;
            
//结果存放到lLineEn中;
            lLineEn[iCount] = lLineUn[iMinii];
            
//将唯一的顶点存放到iPoint数组中;
            if (!s[0].same)
            
{
                Vertex[
0]++;
                Vertex[Vertex[
0]] = s[0].m_iPoint;
            }

            
if (!s[1].same)
            
{
                Vertex[
0]++;
                Vertex[Vertex[
0]] = s[1].m_iPoint;
            }

            
//
            //遍历所有的顶点;改变set数组里面的值,保证前面if条件的正确性;
            
//将同一个联通分量的所有的顶点对应的set数组值全部置为
            
//这些顶点中序号最小点对应的set数组值;
            for ( i = 1; i <= count ; i++ )
            
{
                
//iPoint1,iPoint2有序性??
                if ( set[i] == set[lLineUn[iMinii].m_iPoint2])
                
{
                    
set[i] = set[lLineUn[iMinii].m_iPoint1];
                    
for ( j = 1 ; j <= count ; j++)
                    
{
                        
if ( set[j] == i )
                            
set[j] = set[i];
                    }
//for
                }
//if        
            }
//for
        }
//if
    }
//while
}
// MiniTree

void  Print(Edge *  lLineEn,  int  n)                             // 打印最小生成树
{
    printf(
"The Mini Route is :  ");
    
for (int i = 1; i < n; i++ )
    
{
        printf(
"%4d --> %4d               %6d "
            lLineEn[i].m_iPoint1, lLineEn[i].m_iPoint2, lLineEn[i].key );
    }

}


int  main()
{
    
int n, iCount = 0;

    printf(
"Input Lines number of line: ");
    scanf(
"%d"&n);

    Edge lLineUn[
10000];    // 
    Edge lLineEn[30];        //最多30顶点,

    InputData(lLineUn, n, iCount);
    MiniTree(lLineUn, lLineEn, n, iCount);
    Print(lLineEn, iCount);

    
return 0;
}

 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值