1 /* 2 题意:给出n个长度为7的字符串,一个字符串到另一个的距离为不同的字符数,问所有连通的最小代价是多少 3 Kuskal/Prim: 先用并查集做,简单好写,然而效率并不高,稠密图应该用Prim。这是最小生成数的裸题,然而题目有点坑爹:( 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <string> 8 #include <algorithm> 9 #include <iostream> 10 #include <cmath> 11 using namespace std; 12 13 const int MAXN = 2e3 + 10; 14 const int INF = 0x3f3f3f3f; 15 struct UF 16 { 17 int rt[MAXN]; 18 19 void init(void) {memset (rt, -1, sizeof (rt));} 20 21 int Find(int x) {return (rt[x] == -1) ? x : rt[x] = Find (rt[x]);} 22 23 void Union(int x, int y) 24 { 25 x = Find (x); y = Find (y); 26 if (x < y) rt[x] = y; 27 else rt[y] = x; 28 } 29 30 bool same(int x, int y) {return (Find (x) == Find (y));} 31 }uf; 32 char s[MAXN][10]; 33 struct Node 34 { 35 int u, v, w; 36 }node[MAXN*MAXN/2]; 37 int n, tot; 38 39 bool cmp(Node x, Node y) {return x.w < y.w;} 40 41 void get_w(int x) 42 { 43 for (int i=1; i<x; ++i) 44 { 45 int res = 0; 46 for (int j=0; j<7; ++j) 47 { 48 if (s[i][j] != s[x][j]) res++; 49 } 50 node[++tot].u = i; node[tot].v = x; node[tot].w = res; 51 } 52 } 53 54 int main(void) //POJ 1789 Truck History 55 { 56 // freopen ("POJ_1789.in", "r", stdin); 57 58 while (scanf ("%d", &n) == 1) 59 { 60 if (n == 0) break; 61 62 tot = 0; 63 for (int i=1; i<=n; ++i) 64 { 65 scanf ("%s", s[i]); 66 get_w (i); 67 } 68 sort (node+1, node+1+tot, cmp); 69 70 int ans = 0; uf.init (); 71 for (int i=1; i<=tot; ++i) 72 { 73 int u = node[i].u; int v = node[i].v; int w = node[i].w; 74 if (!uf.same (u, v)) {uf.Union (u, v); ans += w;} 75 } 76 77 printf ("The highest possible quality is 1/%d.\n", ans); 78 } 79 80 return 0; 81 }
时间: 2024-12-25 03:22:19