您的位置:首页 > 其它

poj1789 Truck History(Prim算法实现)

2012-07-30 10:40 337 查看
poj1789 Truck History

题意大概是这样的:用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。

例如有如下4个编号:

aaaaaaa

baaaaaa

abaaaaa

aabaaaa

显然的,第二,第三和第四编号分别从第一编号衍生出来的代价最小,因为第二,第三和第四编号分别与第一编号只有一个字母是不同的,相应的distance都是1,加起来是3。也就是最小代价为3。

问题可以转化为最小代价生成树的问题。因为每两个结点之间都有路径,所以是完全图。首先考虑用Kruskal算法解题,配合Disjoint Set Forest可以达到O(E lgV)。可是最后却无情的TLE了。分析TLE原因,原来K算法需要对所有边进行一次排序,当边数目比较多时,这就是非常耗时的一个工作。尤其本题是完全图,其代价可想而知。

具体实现如下:

#include <stdio.h>

#define SIZE 2012

int map[SIZE][SIZE];

char code[SIZE][10];

int main(){

int N;

int i,j,k,ans,diff,count,min,indexj;

int lowedge[SIZE];

while(scanf("%d",&N),N!=0){

//建图

for(i=0;i<N;i++)

scanf("%s",code[i]);

for(i=0;i<N;i++){

for(j=i;j<N;j++)

{

diff=0;

for(k=0;k<7;k++)

if(code[i][k]!=code[j][k]) diff++;

map[i][j]=map[j][i]=diff;

}

}

/* for(i=0;i<N;i++)

{

for(j=0;j<N;j++)

printf("%d ",map[i][j]);

printf("\n");

}

printf("Input Successs!\n");*/

ans=0;

//初始化flag[SIZE],adjacent[SIZE]

for(i=0;i<N;i++)

{

lowedge[i]=map[0][i];

//printf("%d ",lowedge[i]);

}

//printf("\n");

lowedge[0]=0;

count=N;

while(--count){

min=999;

for(j=0;j<N;j++)

if(lowedge[j]!=0&&lowedge[j]<min)

{ //edge[i]=0表示加入了TE中

min=lowedge[j];

indexj=j;

}

//printf("min=%d\n",min);

ans+=lowedge[indexj];

lowedge[indexj]=0;

for(j=0;j<N;j++)

if(lowedge[j]!=0&&map[indexj][j]<lowedge[j])

lowedge[j]=map[indexj][j];

/*printf("修改后的lowedge[i]:\n");

for(i=0;i<N;i++)

printf("%d ",lowedge[i]);

printf("\n");*/

}

printf("The highest possible quality is 1/%d.\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: