水题。。。
题目大意:
用一个7位的字符串代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。
很容易想到,将每两个顶点间的distance求出作为边权,将题目转化为最小生成树问题。由于是稠密图,所以用prim算法。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int i,j,k,n,m,x,a[2001][2001],ans,minn,d[2001],tot,c[2001]; bool b[2001]; char s[2001][7]; int main() { scanf("%d",&n); while(n){ memset(d,127,sizeof(d)); memset(b,0,sizeof(b)); memset(a,0,sizeof(a)); ans=0;tot=1; for(i=1;i<=n;i++)scanf("%s",s[i]); for(i=1;i<n;i++) for(j=i+1;j<=n;j++){ for(k=0;k<7;k++)if(s[i][k]!=s[j][k])a[i][j]++; a[j][i]=a[i][j]; } c[1]=1;d[1]=0;k=1;b[1]=1; while(tot<n){ minn=2147483647; for(i=1;i<=n;i++) if(!b[i]){ if(d[c[k]]+a[c[k]][i]<d[i])d[i]=d[c[k]]+a[c[k]][i]; if(d[i]<minn){ minn=d[i]; x=i; } } b[x]=1; c[++tot]=x; ans+=d[x]; d[x]=0; k++; } printf("The highest possible quality is 1/%d.\n",ans); scanf("%d",&n); } return 0; }