G. Truck History
Time Limit:2000ms
Case Time Limit:2000ms
Memory Limit:65536KB
SubmitStatus PID: 1908
Font Size:
Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for vegetable delivery, other for furniture, or for bricks. The company has its own code describing each type of a truck. The code is simply a string of exactly seven lowercase letters (each letter on each position has a very special meaning but that is unimportant for this task). At the beginning of company's history, just a single truck type was used but later other types were derived from it, then from the new types another types were derived, and so on.
Today, ACM is rich enough to pay historians to study its history. One thing historians tried to find out is so called derivation plan -- i.e. how the truck types were derived. They defined the distance of truck types as the number of positions with different letters in truck type codes. They also assumed that each truck type was derived from exactly one other truck type (except for the first truck type which was not derived from any other type). The quality of a derivation plan was then defined as
1/Σ(to,td)d(to,td)
where the sum goes over all pairs of types in the derivation plan such that to is the original type and td the type derived from it and d(to,td) is the distance of the types.
Since historians failed, you are to write a program to help them. Given the codes of truck types, your program should find the highest possible quality of a derivation plan.
Input
The input consists of several test cases. Each test case begins with a line containing the number of truck types, N, 2 <= N <= 2 000. Each of the following N lines of input contains one truck type code (a string of seven lowercase letters). You may assume that the codes uniquely describe the trucks, i.e., no two of these N lines are the same. The input is terminated with zero at the place of number of truck types.
Output
For each test case, your program should output the text "The highest possible quality is 1/Q.", where 1/Q is the quality of the best derivation plan.
Sample Input
4 aaaaaaa baaaaaa abaaaaa aabaaaa 0
Sample Output
The highest possible quality is 1/3.
解题思路:该题为最短路径问题,直接用克鲁斯卡尔算法加个并查集即可,只是,前面要预处理一下。
有很多卡车,他们功能不同,编号不同,每辆卡车的编号是7个小写字母要求输出1/Σ(to,td)d(to,td),要最大值,也就是说Σ(to,td)d(to,td)的最小值。公式理解是一大难点,Σ(to,td)d(to,td)他这里是要求卡车t0和td编号不同的字母个数,前面的Σ(to,td)是累加,就是t是从t0到td的意思。
也就是说要求各辆卡车编号不同字母的最短路径,卡车ti到ti+1的路劲长度是这两辆卡车编号不同的字母个数。所以,我们的预处理就是要得出卡车(ti,ti+1)的标号的不同字母个数(i=0;i<m-1;i++),直接存储到结构体数组中备用。后面再用结构体数组中信息用克鲁斯卡尔算法加并查集求出最短路径即可。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n; int t[2002]; //用于并查集,记录节点i的根节点 struct node //用于并查集,存储两辆卡车的编号不同字母情况 { int x; int y; int d; //距离 }relat[4000000]; void exchang() //用于预处理,得出每两辆卡车的编号不同字母情况 { int trick[2002][8]; //用于预处理,得出每两辆卡车的编号 int i,j,cou; int m; for(i=0;i<n;i++) //读入卡车编号信息 scanf("%s",trick[i]); cou=0; for(i=0;i<n;i++) //处理得出卡车i和卡车j编号中不同字母的个数 for(j=i+1;j<n;j++) { int sum=0; for(int k=0;k<7;k++) //每个字母都检索比较 { if(trick[i][k]!=trick[j][k]) sum++; } relat[cou].x=i; //存入结构体数组,用于最短路径求解 relat[cou].y=j; relat[cou].d=sum; cou++; } } bool cmp(node a,node b) //排序,把结构体数组按距离d的值从小到大排序 { return a.d<b.d; } int find(int x) //用于并查集,需找节点x的根节点 { while(x!=t[x]) x=t[x]; return x; } int MST() //克鲁斯卡尔最短路径算法 { int m=n*(n-1); //路径条数 int sum=0,i; sort(relat,relat+m,cmp); //按距离排序 for(i=0;i<n;i++) //每个节点的根节点都是自己本身 t[i]=i; for(i=0;i<m;i++) { int x_f=find(relat[i].x); int y_f=find(relat[i].y); if(x_f!=y_f) //若两个节点不再同一集合,则合并这两个集合 { sum+=relat[i].d; t[y_f]=x_f; } } return sum; } int main() { while(scanf("%d",&n)&&n) { exchang(); //预处理 printf("The highest possible quality is 1/%d.\n",MST()); //求出最短路径,输出 } return 0; }