转载别人写的代码。
有个最小生成树的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;
}
#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;
}