poj 1789 Truck History
题意:用一个7位的string代表一个车的编号,两个编号之间的distance代表这两个编号之间相同位置不同字母的个数。如果一个编号要“衍生”另一个编号,代价是这两个编号之间相应的distance也就是改变字母数,现在要求总的改变数最小,也就是distance之和最小。
4
aaaaaaa
baaaaaa
abaaaaa
aabaaaa
编号2,3,4分别从第一编号衍生出来的代价最小,因为2,3,4分别与第一编号只有一个字母是不同的,相应的distance都是1,加起来是3。也就是总的改变数最小为3。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<map> #include<cstring> #include<vector> using namespace std; class Kru { public: int x,y,dis; }kru[2000000]; char str[2024][2024]; int set[2024]; bool cmp( Kru a, Kru b ) { return a.dis < b.dis; } int find( int x ) { return set[x] == x ? x : set[x] = find( set[x] ); } int Kruscal( int count ) { int sum = 0,X,Y; for( int i = 0 ; i < count ; i ++ ) { if( ( X = find(kru[i].x) )!=( Y = find( kru[i].y ) ) ) { set[Y] = X; sum += kru[i].dis; } } return sum; } int main( ) { int n ; while( scanf( "%d",&n ),n ) { for( int i = 1; i <= n ; i++ ) { scanf( "%s",str[i] ); set[i] = i; } int count = 0; for( int i = 1 ; i <= n ; i ++ ) { for( int j = i + 1; j <= n ; j ++ ) { int sum = 0; for( int k = 0 ; k < 7 ; k ++ ) { if( str[i][k]!=str[j][k] ) sum++; } kru[count].x = i ; kru[count].y = j; kru[count++].dis = sum; } } sort( kru , kru + count , cmp ); printf( "The highest possible quality is 1/%d.\n",Kruscal( count ) ); } //system( "pause" ); return 0; }