标题: | Prim和Kruskal最小生成树 |
时 限: | 2000 ms |
内存限制: | 15000 K |
总时限: | 3000 ms |
描述: | 给出一个矩阵,要求以矩阵方式单步输出生成过程。 要求先输出Prim生成过程,再输出Kruskal,每个矩阵输出后换行。 注意,题中矩阵表示无向图 |
输入: | 结点数 矩阵 |
输出: | Prim: 矩阵输出 Kruskal: 矩阵输出 |
输入样例: | 3 0 1 3 1 0 2 3 2 0 |
输出样例: | 3
1 0 2 3 2 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 2 0 2 0 Kruskal: 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 2 0 2 0 |
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 100//最大顶点数
#define OK 1
#define ERROR 0
typedef int VertexType;//顶点类型
邻接矩阵定义
typedef struct
{
int adj;//相邻与否,或权值大小
}ArcCell;
typedef struct _MGraph
{
VertexType vexs[MaxVertexNum];//顶点表
ArcCell arcs[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表
int vexnum;//图中当前的顶点数
}MGragh;
typedef struct _closedge
{
VertexType adjvex;
int lowcost;
}Closedge[MaxVertexNum];
int minimum(Closedge c,int num)
{
int m,result;
for(m=0;m<num;m++)
{
if(c[m].lowcost!=0)
{
result=m;
break;
}
}
for(m=0;m<num;m++)
{
if(c[m].lowcost!=0&&c[m].lowcost<c[result].lowcost)
result=m;
}
return result;
}
void PrintG(MGragh &G)
{
int m,n;
for(m=0;m<G.vexnum;m++)
{
for(n=0;n<G.vexnum;n++)
{
printf("%d ",G.arcs[m][n].adj);
}
printf("\n");
}
printf("\n");
}
void MiniSpanTree_Prim(MGragh &G,int u)
{
MGragh U;U.vexnum=G.vexnum;Closedge closedge;//U是用来输出的矩阵
int k=u;
int i,j;
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
{
if (G.arcs[i][j].adj==0)
{
G.arcs[i][j].adj=32767;
}
}
for(i=0;i<U.vexnum;i++)
for(j=0;j<U.vexnum;j++)
{
U.arcs[i][j].adj=0;
}
for(j=0;j<G.vexnum;j++)
if(j!=k)
{
closedge[j].adjvex=k;
closedge[j].lowcost=G.arcs[k][j].adj;
}
closedge[k].lowcost=0;//初始,U={u}
PrintG(U);
for(i=1;i<G.vexnum;i++)//其余1到G.vexnum个顶点
{
k=minimum(closedge,G.vexnum);
U.arcs[closedge[k].adjvex][G.vexs[k]].adj=closedge[k].lowcost;
U.arcs[G.vexs[k]][closedge[k].adjvex].adj=closedge[k].lowcost;
PrintG(U);
closedge[k].lowcost=0;//第k顶点并入U集
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[k][j].adj<closedge[j].lowcost)
{
closedge[j].adjvex=G.vexs[k];
closedge[j].lowcost=G.arcs[k][j].adj;
}
}
}//for i
}
Kruskal/
typedef struct _Node
{
VertexType v1,v2;
int cost;
}SqNode;
SqNode *CreatList(MGragh &G,int &edgenums)
{
int i,j,edges=0;
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if (G.arcs[i][j].adj!=0)
{
edges++;
}
//edges=edges/2;
edgenums=edges;
SqNode *list=(SqNode*)malloc(sizeof(SqNode)*edges);
int num=0;
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
//printf("num %d\n",num);
if(G.arcs[i][j].adj!=0)
{
list[num].v1=i;
list[num].v2=j;
list[num].cost=G.arcs[i][j].adj;
num++;
}
}
}
return list;
}
void SortSqList(SqNode* &list,int num)
{
SqNode temp;
int i=num,j;
while (i>0)
{
for (j=0;j<i-1;j++)
{
if (list[j].cost>list[j+1].cost)
{
temp=list[j];
list[j]=list[j+1];
list[j+1]=temp;
}
}
i--;
}
}
void MiniSpanTree_Kuskal(MGragh &G)
{
MGragh U;U.vexnum=G.vexnum;//U是用来输出的矩阵
for(int i=0;i<U.vexnum;i++)
for(int j=0;j<U.vexnum;j++)
{
U.arcs[i][j].adj=0;
}
int edgenums=0,u1,v1,sn1,sn2;
SqNode *Edge=CreatList(G,edgenums);
SortSqList(Edge,edgenums);
int i,j,k;
int *vset=(int*)malloc(sizeof(int)*edgenums);
for (i=0;i<G.vexnum;i++)
{
vset[i]=i;
}
k=1;j=0;
PrintG(U);
while (k<G.vexnum)
{
u1=Edge[j].v1;v1=Edge[j].v2;
sn1=vset[u1];sn2=vset[v1];
if (sn1!=sn2)
{
U.arcs[u1][v1].adj=Edge[j].cost;
U.arcs[v1][u1].adj=Edge[j].cost;
PrintG(U);
k++;
for (i=0;i<G.vexnum;i++)
if (vset[i]==sn2)
vset[i]=sn1;
}
j++;
}
}
int main()
{
int vertexnum,i,j;
scanf("%d",&vertexnum);
MGragh M;
M.vexnum=vertexnum;
for(i=0;i<vertexnum;i++)
{
M.vexs[i]=i;
}
for(i=0;i<vertexnum;i++)
for(j=0;j<vertexnum;j++)
{
scanf("%d",&M.arcs[i][j].adj);
}
printf("Prim:\n");
MiniSpanTree_Prim(M,0);
printf("Kruskal:\n");
MiniSpanTree_Kuskal(M);
return 0;
}