题意:给定n个长为7的字符串,定义一个串衍生出另一个的代价是它们不同的字母数。选择一个串作为起始串,求衍生出所有出现串的最小代价。(衍生出的串也可以再次衍生别的串)
解:最小生成树即可。复习一下prim毕竟数据结构课还要考这玩意qaq
1 #include<stdio.h> 2 #include <algorithm> 3 #include <queue> 4 #include <math.h> 5 using namespace std; 6 #define ll long long 7 #define maxx 2005 8 #define inf 0x3f 9 //#define int long long 10 struct edge{ 11 int u,v,w; 12 int nxt; 13 }e[maxx*2]; 14 int head[maxx]={0},cnt=0; 15 void add(int u,int v,int w){ 16 e[++cnt].u=u; 17 e[cnt].v=v; 18 e[cnt].w=w; 19 e[cnt].nxt=head[u]; 20 head[u]=cnt; 21 } 22 int n; 23 int dis[maxx],mp[maxx][maxx],vis[maxx]; 24 char s[maxx][10]; 25 int distanc(int a,int b){ 26 int ans=0; 27 for(int i=0;i<7;i++) 28 if(s[a][i]!=s[b][i]) 29 ans++; 30 return ans; 31 } 32 int prim(){ 33 int ans=0; 34 memset(vis,0,sizeof vis); 35 for(int i=2;i<=n;i++) 36 dis[i]=mp[1][i]; 37 vis[1]=1; 38 int x; 39 for(int i=1;i<n;i++){ 40 int temp=inf; 41 for(int j=1;j<=n;j++){ 42 if(!vis[j]&&dis[j]<temp){ 43 temp=dis[j]; 44 x=j; 45 } 46 } 47 ans+=dis[x]; 48 vis[x]=1; 49 for(int j=1;j<=n;j++) 50 if(!vis[j]) 51 dis[j]=min(dis[j],mp[x][j]); 52 } 53 return ans; 54 } 55 signed main() { 56 while (~scanf("%d", &n)) { 57 if (n == 0) 58 break; 59 for (int i = 1; i <= n; i++) 60 scanf("%s", s[i]); 61 for (int i = 1; i <= n; i++) 62 for (int j = i + 1; j <= n; j++) 63 mp[i][j] = mp[j][i] = distanc(i, j); 64 printf("The highest possible quality is 1/%d.\n", prim()); 65 } 66 return 0; 67 }