您的位置:首页 > 其它

POJ 1789 Truck History (最小生成树)

2014-09-12 18:50 274 查看
题目类型 最小生成树

题目意思
给出最多2000个长度为7的字符串, 现在要求除了某个字符串外每一个字符串都必须找一个源子符串, 使从源字符串转化出其他的字符串的总代价最小
假设 abaaaaa 的源子符串是 aaaaaaa 的话那么从 aaaaaaa 转化出 abaaaaa 的代价就是不同字符的位数(这个例子就只有1位不同 代价为1)

解题方法

很明显的最小生成树 每个字符串为一个点 字符串间的转化的代价为 边 的权值 最小生成树对应的边权和即为最小代价

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的

以下代码用的是kruscal算法

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 2000 + 10;
char str[maxn][10];
int f[maxn];

struct Node {
int u, v, w;
bool operator < (const Node & rhs) const {
return w < rhs.w;
}
}E[maxn*maxn];

int diff(int a, int b) {
int res = 0;
for( int i=0; i<7; i++ ) {
if(str[a][i] != str[b][i]) res++;
}
return res;
}

int find(int x) {
return f[x] == x ? x : find(f[x]);
}

int main() {
freopen("in", "r", stdin);
int n;
while(scanf("%d", &n), n) {
for( int i=0; i<n; i++ ) {
scanf("%s", str[i]);
f[i] = i;
}
int k = 0;
for( int i=0; i<n; i++ ) {
for( int j=i+1; j<n; j++ ) {
E[k].u = i; E[k].v = j; E[k].w = diff(i, j);
k++;
}
}
sort(E, E+k);
int res = 0;
int tn = n;
for( int i=0; i<k; i++ ) {
int u = E[i].u, v = E[i].v;
int x = find(u), y = find(v);
if(x != y) {
res += E[i].w;
f[x] = y;
tn--;
if(tn == 1) break;
}
}
printf("The highest possible quality is 1/%d.\n", res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: