题目链接:http://poj.org/problem?id=1789
裸的最小生成树,但是题意非常不好理解,就是说每一串字符相当于一个点,任意两个字符串中不容字符的个数相当于边权,这样来建图求最小生成树。还是只会用kruskal啊。。
view code
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <cmath>
6 #include <algorithm>
7 using namespace std;
8 struct edge
9 {
10 int u, v, w;
11 }e[4000000];
12 char data[2001][8];
13 int p[2001];
14 int tot;
15 int cmp(edge a, edge b)
16 {
17 return a.w < b.w;
18 }
19 int find(int x)
20 {
21 return p[x] != x ? p[x] = find(p[x]) : x;
22 }
23 void add(int x, int y, int z)
24 {
25 tot++;
26 e[tot].u = x;
27 e[tot].v = y;
28 e[tot].w = z;
29 }
30 int main()
31 {
32 int r1, r2, sum, n, ans;
33 while (scanf("%d", &n) != EOF)
34 {
35 if (n == 0) break;
36 tot = 0; memset(e, 0, sizeof(e)); ans = 0;
37 for (int i = 0; i < n; i++) p[i] = i;
38 for (int i = 0; i < n; i++) scanf("%s", data[i]);
39 for (int i = 0; i < n; i++)
40 for (int j = 0; j < n; j++)
41 {
42 sum = 0;
43 if (i != j)
44 for (int k = 0; k < 8; k++)
45 if (data[i][k] != data[j][k]) sum++;
46 add(i, j, sum);
47 }
48 sort(e + 1, e + 1 + tot, cmp);
49 for (int i = 1; i <= tot; i++)
50 {
51 r1 = find(e[i].u); r2 = find(e[i].v);
52 if (r1 != r2)
53 {
54 p[r2] = r1;
55 ans += e[i].w;
56 }
57 }
58 printf("The highest possible quality is 1/%d.\n", ans);
59 }
60 return 0;
61