题意:题意杀...用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。
思路:计算出距离然后套模板即可,关键是要看懂题目
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 2010
const int maxm = 2000*2000+10;
#define LL long long
int cas=1,T;
struct Edge
{
int u,v,dist;
Edge(){}
Edge(int u,int v,int dist):u(u),v(v),dist(dist){}
bool operator < (const Edge &rhs)const
{
return dist < rhs.dist;
}
};
int n,m;
Edge edges[maxm];
int pre[maxn];
int Find(int x)
{
return pre[x] == -1?x:pre[x]=Find(pre[x]);
}
void init()
{
m=0;
memset(pre,-1,sizeof(pre));
}
void AddEdge(int u,int v,int dist)
{
edges[m++]=Edge(u,v,dist);
}
int Kruskal()
{
int sum = 0;
int cnt = 0;
sort(edges,edges+m);
for (int i = 0;i<m;i++)
{
int u = edges[i].u;
int v = edges[i].v;
if (Find(u)!=Find(v))
{
sum+=edges[i].dist;
pre[Find(u)]=Find(v);
if (++cnt >=n-1)
return sum;
}
}
return -1;
}
char str[maxn][10];
int getdist(int i,int j)
{
int sum = 0;
for (int k = 0;k<7;k++)
if (str[i][k]!=str[j][k])
sum++;
return sum;
}
int main()
{
while (scanf("%d",&n) && n)
{
for (int i =0;i<n;i++)
scanf("%s",str[i]);
init();
for (int i = 0;i<n;i++)
for (int j = i+1;j<n;j++)
AddEdge(i,j,getdist(i,j));
printf("The highest possible quality is 1/%d.\n",Kruskal());
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}