设最小生成树的节点的集合为U
候选集:待加入最小生成树的节点的集合
割 边:候选集中节点与U中节点的连接形成的边为割边
class TTreeEdge //存储边信息(起始点,终止点,权值)
{
float v1,v2; //v1:起始点 v2:终止点
long weight; //权值
}
public class Prim {
public long MinSpanningTree(int[][] g,int n,TTreeEdge[] minTree)
/**
* g 输入量,存储图信息的矩阵
* n 输入量,图中的节点数目
* minTree 存储最小生成树信息
*/
{
class TCloseRec //定义一个候选集,存储没有加入最小生成树的节点信息和边信息
{
long vex;
long lowcost;
}
int i,j,k;
TCloseRec[] close=new TCloseRec[n];
close[0]=new TCloseRec();
for(i=1;i<n;i++) //初始化候选集,假设节点0已经加入U
{
close[i]=new TCloseRec();
close[i].vex=0;
close[i].lowcost=g[i][0];
}
close[0].lowcost=0; //若节点加入U,则设置close[i].lowcost为0
for(i=0;i<n-1;i++)
{
for(k=1;k<n;k++)
if(close[k].lowcost!=0) //在候选集中寻找第一个未加入U的节点
break;
for(j=k+1;j<n;j++)
if(close[j].lowcost!=0)
if(close[j].lowcost<close[k].lowcost) //寻找权值最小的节点
k=j;
minTree[i].v1=k; //将权值最小的节点加入U
minTree[i].v2=close[k].vex;
minTree[i].weight=close[k].lowcost;
close[k].lowcost=0; //标志节点K已经加入U
//调整候选集
for(j=1;j<n;j++) //检查每个邻接与k的边
{
if(close[j].lowcost>g[j][k])
{
close[j].lowcost=g[j][k];
close[j].vex=k;
}
}
}
return i;
}
public static void main(String[] args) {
// TODO code application logic here
Prim p=new Prim();
int minValue=0;
int[][] g=new int[5][5];
for(int i=0;i<5;i++)
g[i][i]=0;
g[0][1]=g[1][0]=1;
g[0][2]=g[2][0]=100;
g[0][3]=g[3][0]=100;
g[0][4]=g[4][0]=6;
g[1][2]=g[2][1]=2;
g[1][3]=g[3][1]=4;
g[1][4]=g[4][1]=5;
g[2][3]=g[3][2]=8;
g[2][4]=g[4][2]=100;
g[3][4]=g[4][3]=9;
TTreeEdge[] tree=new TTreeEdge[4];
for(int t=0;t<4;t++)
{
tree[t]=new TTreeEdge();
}
long num=p.MinSpanningTree(g, 5, tree);
System.out.println("最小生成树共有"+num+"条边");
for(int r=0;r<4;r++)
{
System.out.print(tree[r].v1+"----"+tree[r].v2+"权值为:"+tree[r].weight);
System.out.println();
minValue+=tree[r].weight;
}
System.out.println("最大权值为:"+minValue);
}
}