Kuskal/Prim POJ 1789 Truck History

 

题目传送门

 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 }

 

 1 /*

 2  模版搞错了,纠结半天。。。算法还是想清楚才行啊  3 */

 4 #include <cstdio>

 5 #include <algorithm>

 6 #include <cstring>

 7 #include <string>

 8 #include <iostream>

 9 #include <vector>

10 using namespace std; 11 

12 const int MAXN = 2e3 + 10; 13 const int INF = 0x3f3f3f3f; 14 int d[MAXN]; 15 int w[MAXN][MAXN]; 16 bool vis[MAXN]; 17 int n, tot; 18 char s[MAXN][10]; 19 

20 int Prim(int s) 21 { 22     memset (vis, false, sizeof (vis)); 23     for (int i=2; i<=n; ++i)    d[i] = w[1][i]; 24     vis[s] = true;    d[s] = 0;    int ans = 0; 25 

26     for (int i=2; i<=n; ++i) 27  { 28         int mn = INF;    int x = -1; 29         for (int j=1; j<=n; ++j) 30  { 31             if (!vis[j] && d[j] < mn)    mn = d[x=j]; 32  } 33         vis[x] = true;    ans += mn; 34         for (int j=1; j<=n; ++j) 35  { 36             if (!vis[j] && d[j] > w[x][j])    d[j] = w[x][j]; 37  } 38  } 39 

40     return ans; 41 } 42 

43 void get_w(int x) 44 { 45     for (int i=1; i<x; ++i) 46  { 47         int res = 0; 48         for (int j=0; j<7; ++j) 49  { 50             if (s[i][j] != s[x][j])    res++; 51  } 52         w[i][x] = w[x][i] = res; 53  } 54 } 55 

56 int main(void)        //POJ 1789 Truck History

57 { 58     // freopen ("POJ_1789.in", "r", stdin);

59 

60     while (scanf ("%d", &n) == 1) 61  { 62         if (n == 0)    break; 63         memset (w, 0, sizeof (w)); 64         for (int i=1; i<=n; ++i) 65  { 66             scanf ("%s", s[i]); get_w (i); 67  } 68 

69         printf ("The highest possible quality is 1/%d.\n", Prim (1)); 70  } 71 

72     return 0; 73 }
Prim

 

你可能感兴趣的:(history)