第一次敲prim算法
保存了路径的代码:没有将lowcost和mst合并
#include <cstdio>
#include <string.h>
//Prim
const int maxn=2010;
const int inf=10000;
int lowcost[maxn],mst[maxn];
int map[maxn][maxn];
int n,m;
char str[maxn][10];
void Prim (int u0)//从
{
int i,j;
int ans=0;
for (i=1 ; i<=n ; ++i)
lowcost[i]=map[u0][i],mst[i]=u0;
mst[u0]=-1;
for (i=1 ; i<n ; ++i)
{
int min=inf;
int v=-1;
for (j=1 ; j<=n ; ++j)
if(mst[j]!=-1 && lowcost[j]<min)//找到mst不为-1 且lowcost最小的边
v=j , min=lowcost[j];
if(v!=-1)
{
//printf("%d %d %d\n",v,mst[v],lowcost[v]);
mst[v]=-1;//将v加入T中
ans+=lowcost[v];
for (j=1 ; j<=n ; ++j)
if(mst[j]!=-1 && map[v][j]<lowcost[j])//更新新加入的v与原来的点的最短路
lowcost[j]=map[v][j],mst[j]=v;
}
}
printf("The highest possible quality is 1/%d.\n",ans);
}
int main ()
{
int i,j,k;
int u,v,w;
while (scanf( "%d" , &n )!=EOF && n)
{
memset (map , 0 , sizeof(map));
for (i=1 ; i<=n ; ++i)
{
scanf("%s",str+i);
}
for (i=1 ; i<=n ; ++i)
for (j=i ; j<=n ; ++j)
{
if(i==j)map[i][j]=0;
else
{
for (k=0 ; k<7 ; ++k)
if(str[i][k]!=str[j][k])++map[i][j];
map[j][i]=map[i][j];
}
}
Prim(1);
}
return 0;
}
不保存路径的方法:
#include <cstdio>
#include <string.h>
//Prim
const int maxn=2010;
const int inf=10000;
int mst[maxn];
int map[maxn][maxn];
int n,m;
char str[maxn][10];
void Prim (int u0)//
{
int i,j;
int ans=0;
for (i=1 ; i<=n ; ++i)
mst[i]=map[u0][i];
mst[u0]=-1;
for (i=1 ; i<n ; ++i)
{
int min=inf;
int v=-1;
for (j=1 ; j<=n ; ++j)
if(mst[j]!=-1 && mst[j]<min)v=j , min=mst[j];
if(v!=-1)
{
//printf("%d %d %d\n",v,mst[v],lowcost[v]);
ans+=mst[v];
mst[v]=-1;//将v加入T中
for (j=1 ; j<=n ; ++j)
if(mst[j]!=-1 && map[v][j]<mst[j])//更新新加入的v与原来的点的最短路
mst[j]=map[v][j];
}
}
printf("The highest possible quality is 1/%d.\n",ans);
}
int main ()
{
int i,j,k;
int u,v,w;
while (scanf( "%d" , &n )!=EOF && n)
{
memset (map , 0 , sizeof(map));
for (i=1 ; i<=n ; ++i)
{
scanf("%s",str+i);
}
for (i=1 ; i<=n ; ++i)
for (j=i ; j<=n ; ++j)
{
if(i==j)map[i][j]=0;
else
{
for (k=0 ; k<7 ; ++k)
if(str[i][k]!=str[j][k])++map[i][j];
map[j][i]=map[i][j];
}
}
Prim(1);
}
return 0;
}
2个方法 时间上没什么太大区别