【最小生成树】Truck History POJ - 1789

Truck History POJ - 1789

题意:

给定\(n\)个互不相同的长度为\(7\)的字符串,将两个字符串之间的距离定义为两串中字符不同的位置个数,问\(1/Q\)的最大值,其中\(Q=\sum^{t_d}_{t_0}{d({t_0},{t_d})}\)

思路:

求的就是最小生成树的总边权……除了距离需要另外算一下以外就是套模板。

const int maxn = 2000 + 100;
const int maxm = 4000000 + 100;

int fa[maxn], tmp[maxm];
int u[maxm], v[maxm];
int w[maxm];
int n, m;
string s[maxn];

int find(int x) { 
    return fa[x] == x ? x : fa[x] = find(fa[x]); 
}
bool cmp(int i, int j) {
    return w[i] < w[j];
}

int count(string s1, string s2) {
    int a = 0;
    for (int i = 0; i < 7; i++) {
        if (s1[i] != s2[i]) a++;
    }
    return a;
}

double solve() {
    int ans = 0;
    for (int i = 0; i < maxn; i++) fa[i] = i;
    for (int i = 0; i < m; i++) tmp[i] = i;
    sort(tmp, tmp + m, cmp);
    for (int i = 0; i < m; i++) {
        int e = tmp[i];
        int from = find(u[e]);
        int to = find(v[e]);
        if (from != to) {
            ans += w[e];
            fa[from] = to;
        }
    }
    return ans;
}

int main()
{
    //ios::sync_with_stdio(false);
    while (cin >> n && n) {
        m = 0;
        for (int i = 1; i <= n; i++) {
            cin >> s[i];
            for (int j = i - 1; j >= 1; j--) {
                int k = count(s[i], s[j]);
                u[m] = i; v[m] = j; w[m] = k; m++;
                u[m] = j; v[m] = i; w[m] = k; m++;
            }
        }
        cout << "The highest possible quality is 1/" << solve() << "." << endl;
    }
    return 0;
}
posted @ 2020-08-14 18:00  StreamAzure  阅读(91)  评论(0编辑  收藏  举报